From 45f305845a1f10bc29e2b55bcabf207178d54856 Mon Sep 17 00:00:00 2001
From: algasami <105358814+algasami@users.noreply.github.com>
Date: Sat, 11 May 2024 18:48:28 +0800
Subject: [PATCH] added title tags
---
app/[lang]/posts/[slug]/page.tsx | 31 ++++++++++-------
app/components/mdxHeadings/index.tsx | 34 +++++++++++++++++++
.../mdxHeadings/mdxheadings.module.scss | 9 +++++
app/components/postBody/PostBody.module.scss | 5 +++
app/styles/globals.scss | 2 +-
contentlayer.config.ts | 3 ++
package.json | 1 +
pnpm-lock.yaml | 27 ++++++++++++---
8 files changed, 95 insertions(+), 17 deletions(-)
create mode 100644 app/components/mdxHeadings/index.tsx
create mode 100644 app/components/mdxHeadings/mdxheadings.module.scss
diff --git a/app/[lang]/posts/[slug]/page.tsx b/app/[lang]/posts/[slug]/page.tsx
index a7af8f1..f662227 100644
--- a/app/[lang]/posts/[slug]/page.tsx
+++ b/app/[lang]/posts/[slug]/page.tsx
@@ -1,21 +1,19 @@
import { useMDXComponent } from "next-contentlayer/hooks";
-import Head from "next/head";
import PostLayout, {
- PostForPostLayout,
RelatedPostForPostLayout,
} from "../../../components/postLayout";
import { allPostsNewToOld } from "../../../components/contentLayerAdapter";
import { Metadata, ResolvingMetadata } from "next";
import { NoSsr } from "@mui/material";
import { Locale } from "i18n-config";
-
-type PostForPostPage = PostForPostLayout & {
- title: string;
- description: string;
- body: {
- code: string;
- };
-};
+import {
+ MdxH1,
+ MdxH2,
+ MdxH3,
+ MdxH4,
+ MdxH5,
+ MdxH6,
+} from "app/components/mdxHeadings";
export function generateStaticParams({ params }: { params: { lang: Locale } }) {
const arr = allPostsNewToOld
@@ -49,6 +47,15 @@ export function generateMetadata(
};
}
+const mdxComponents = {
+ h1: MdxH1,
+ h2: MdxH2,
+ h3: MdxH3,
+ h4: MdxH4,
+ h5: MdxH5,
+ h6: MdxH6,
+};
+
export default function PostSlugPage({ params }: TProps) {
const { post, lang, prevPost, nextPost, notFound } = buildProps(
params.slug,
@@ -71,7 +78,7 @@ export default function PostSlugPage({ params }: TProps) {
nextPost={nextPost}
locale={lang}
>
-
+
)}
@@ -89,7 +96,7 @@ const buildProps = (slug: string, lang: Locale) => {
};
}
const postFull = filteredPosts[postIndex];
- const post: PostForPostPage = {
+ const post = {
title: postFull.title,
date: postFull.date,
description: postFull.description,
diff --git a/app/components/mdxHeadings/index.tsx b/app/components/mdxHeadings/index.tsx
new file mode 100644
index 0000000..e7b96c4
--- /dev/null
+++ b/app/components/mdxHeadings/index.tsx
@@ -0,0 +1,34 @@
+"use client";
+import Link from "next/link";
+import styles from "./mdxheadings.module.scss";
+import { useState, useEffect } from "react";
+
+const MdxHeading = ({ h, id, children }) => {
+ const [hasMounted, setHasMounted] = useState(false);
+ const Header = h;
+ useEffect(() => {
+ setHasMounted(true);
+ }, []);
+ if (!hasMounted) {
+ return undefined;
+ }
+ if (id) {
+ return (
+
+
+
+ );
+ }
+ return
{children}
;
+};
+
+// cycle through and make H1 - H6 heading tags to use
+export const MdxH1 = (props) => ;
+export const MdxH2 = (props) => ;
+export const MdxH3 = (props) => ;
+export const MdxH4 = (props) => ;
+export const MdxH5 = (props) => ;
+export const MdxH6 = (props) => ;
diff --git a/app/components/mdxHeadings/mdxheadings.module.scss b/app/components/mdxHeadings/mdxheadings.module.scss
new file mode 100644
index 0000000..4cd7c4c
--- /dev/null
+++ b/app/components/mdxHeadings/mdxheadings.module.scss
@@ -0,0 +1,9 @@
+.mdx_heading:hover::before {
+ content: "#";
+ position: absolute;
+ margin-left: -1.6ch;
+ padding-right: 0.2ch;
+ display: inline;
+ color: #505363;
+ font-size: 100%;
+}
diff --git a/app/components/postBody/PostBody.module.scss b/app/components/postBody/PostBody.module.scss
index 83c84e3..99b9866 100644
--- a/app/components/postBody/PostBody.module.scss
+++ b/app/components/postBody/PostBody.module.scss
@@ -33,8 +33,13 @@
}
a {
+ @apply no-underline;
+ }
+
+ a:not(:has(h1, h2, h3, h4, h5, h6)) {
@apply text-blue-500 dark:text-blue-400 underline hover:no-underline;
}
+
code {
@apply font-mono font-normal;
}
diff --git a/app/styles/globals.scss b/app/styles/globals.scss
index 0ca3a85..42be79c 100644
--- a/app/styles/globals.scss
+++ b/app/styles/globals.scss
@@ -79,7 +79,7 @@ code {
a.anchor {
display: flex;
position: relative;
- top: -250px;
+ top: -200px;
visibility: hidden;
}
diff --git a/contentlayer.config.ts b/contentlayer.config.ts
index 3f4e561..40580c4 100644
--- a/contentlayer.config.ts
+++ b/contentlayer.config.ts
@@ -1,7 +1,9 @@
import { defineDocumentType, makeSource } from "contentlayer/source-files";
+import rehypeAutolinkHeadings from "rehype-autolink-headings";
import rehypeCodeTitles from "rehype-code-titles";
import rehypeKatex from "rehype-katex";
import rehypePrism from "rehype-prism-plus";
+import rehypeSlug from "rehype-slug";
import remarkMath from "remark-math";
export const Post = defineDocumentType(() => ({
@@ -51,6 +53,7 @@ export default makeSource({
mdx: {
remarkPlugins: [remarkMath],
rehypePlugins: [
+ rehypeSlug,
rehypeCodeTitles,
[rehypePrism, { ignoreMissing: true }],
rehypeKatex,
diff --git a/package.json b/package.json
index 9169699..48e1679 100644
--- a/package.json
+++ b/package.json
@@ -32,6 +32,7 @@
"rehype-code-titles": "^1.2.0",
"rehype-katex": "^7.0.0",
"rehype-prism-plus": "^2.0.0",
+ "rehype-slug": "^6.0.0",
"remark-math": "^6.0.0",
"sass": "^1.71.1",
"serve": "^14.2.1",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 0bb6c3d..43df395 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -65,6 +65,9 @@ dependencies:
rehype-prism-plus:
specifier: ^2.0.0
version: 2.0.0
+ rehype-slug:
+ specifier: ^6.0.0
+ version: 6.0.0
remark-math:
specifier: ^6.0.0
version: 6.0.0
@@ -1490,10 +1493,6 @@ packages:
peerDependencies:
'@effect-ts/otel-node': '*'
peerDependenciesMeta:
- '@effect-ts/core':
- optional: true
- '@effect-ts/otel':
- optional: true
'@effect-ts/otel-node':
optional: true
dependencies:
@@ -4675,6 +4674,10 @@ packages:
resolve-pkg-maps: 1.0.0
dev: true
+ /github-slugger@2.0.0:
+ resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==}
+ dev: false
+
/glob-parent@5.1.2:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
engines: {node: '>= 6'}
@@ -4865,6 +4868,12 @@ packages:
web-namespaces: 2.0.1
dev: false
+ /hast-util-heading-rank@3.0.0:
+ resolution: {integrity: sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA==}
+ dependencies:
+ '@types/hast': 3.0.4
+ dev: false
+
/hast-util-is-element@3.0.0:
resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==}
dependencies:
@@ -7032,6 +7041,16 @@ packages:
unist-util-visit: 5.0.0
dev: false
+ /rehype-slug@6.0.0:
+ resolution: {integrity: sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A==}
+ dependencies:
+ '@types/hast': 3.0.4
+ github-slugger: 2.0.0
+ hast-util-heading-rank: 3.0.0
+ hast-util-to-string: 3.0.0
+ unist-util-visit: 5.0.0
+ dev: false
+
/rehype-stringify@9.0.4:
resolution: {integrity: sha512-Uk5xu1YKdqobe5XpSskwPvo1XeHUUucWEQSl8hTrXt5selvca1e8K1EZ37E6YoZ4BT8BCqCdVfQW7OfHfthtVQ==}
dependencies: