aboutsummaryrefslogtreecommitdiff
path: root/src/pages/Post.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/pages/Post.tsx')
-rw-r--r--src/pages/Post.tsx74
1 files changed, 32 insertions, 42 deletions
diff --git a/src/pages/Post.tsx b/src/pages/Post.tsx
index c17873c..5c0f0ca 100644
--- a/src/pages/Post.tsx
+++ b/src/pages/Post.tsx
@@ -1,40 +1,36 @@
-import { useEffect, useState } from "react";
import { useParams, Link } from "react-router-dom";
-import matter from "gray-matter";
-import ReactMarkdown from "react-markdown";
import CodeSnippet from "../components/CodeSnippet";
import LinkWithIcon from "../components/LinkWithIcon";
import NotFoundPage from "./404Page";
-interface PostMeta {
- title: string;
- date: string;
- cover?: string;
+interface PostFile {
+ attributes: {
+ title: string;
+ date: string;
+ cover?: string;
+ };
+ markdown: string;
+ ReactComponent: React.FC<any>;
}
+const posts = import.meta.glob("../blog/*.md", {
+ eager: true,
+}) as Record<string, PostFile>;
+
export default function Post() {
const { slug } = useParams<{ slug: string }>();
- const [meta, setMeta] = useState<PostMeta | null>(null);
- const [content, setContent] = useState("");
- const [notFound, setNotFound] = useState(false);
- useEffect(() => {
- import(`../blog/${slug}.md?raw`)
- .then((m) => {
- const { data, content } = matter(m.default);
- setMeta(data as PostMeta);
- setContent(content);
- })
- .catch(() => setNotFound(true));
- }, [slug]);
+ const match = Object.entries(posts).find(([path]) =>
+ path.endsWith(`${slug}.md`)
+ );
- if (!meta) return null;
- if (notFound) return <NotFoundPage />;
+ if (!match) return <NotFoundPage />;
+ const { attributes: meta, ReactComponent: Content } = match[1];
return (
<article className="prose prose-zinc dark:prose-invert mx-auto px-4 py-10">
<Link to="/blog" className="no-underline">
- ← Back
+ ← Back
</Link>
{meta.cover && (
@@ -49,27 +45,21 @@ export default function Post() {
<p className="text-sm text-zinc-500 mb-8">
{new Date(meta.date).toLocaleDateString("de-DE")}
</p>
-
- <article className="markdown-body">
- <ReactMarkdown
- components={{
- code({ children }) {
- const text = String(children).replace(/\n$/, "");
- return <CodeSnippet code={text} initialLines={5} />;
- },
- a({ href = "", children, ...props }) {
- return (
- <LinkWithIcon href={href} {...props}>
- {children}
- </LinkWithIcon>
- );
- },
- }}
- >
- {content}
- </ReactMarkdown>
- </article>
+ {/* The Markdown, already a React component */}
+ <Content
+ components={{
+ code({ children }: any) {
+ return (
+ <CodeSnippet
+ code={String(children).replace(/\n$/, "")}
+ initialLines={5}
+ />
+ );
+ },
+ a: LinkWithIcon,
+ }}
+ />
</article>
);
} \ No newline at end of file