MDX Starter (#3)

Reviewed-on: mthomson/michaelthomson#3
Co-authored-by: Michael Thomson <michael@michaelthomson.dev>
Co-committed-by: Michael Thomson <michael@michaelthomson.dev>
This commit is contained in:
Michael Thomson 2024-01-18 14:01:49 +00:00 committed by mthomson
parent a9c847ad0b
commit a25eb1d730
8 changed files with 1529 additions and 90 deletions

17
app/blog/[slug]/page.tsx Normal file
View File

@ -0,0 +1,17 @@
import { getAllPosts, getPostBySlug } from "@/lib/posts";
import { MDXRemote } from 'next-mdx-remote/rsc'
export async function generateStaticParams() {
const posts = getAllPosts(["slug"]);
return posts.map((post) => ({ slug: post.slug }));
}
export default async function Page({ params }: { params: { slug: string } }) {
const post = getPostBySlug(params.slug, ["title", "content"]);
return (
<MDXRemote
source={post.content}
/>
)
}

View File

@ -1,27 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
:root {
--foreground-rgb: 0, 0, 0;
--background-start-rgb: 214, 219, 220;
--background-end-rgb: 255, 255, 255;
}
@media (prefers-color-scheme: dark) {
:root {
--foreground-rgb: 255, 255, 255;
--background-start-rgb: 0, 0, 0;
--background-end-rgb: 0, 0, 0;
}
}
body {
color: rgb(var(--foreground-rgb));
background: linear-gradient(
to bottom,
transparent,
rgb(var(--background-end-rgb))
)
rgb(var(--background-start-rgb));
}

View File

@ -5,8 +5,8 @@ import './globals.css'
const inter = Inter({ subsets: ['latin'] })
export const metadata: Metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
title: 'Michael Thomson',
description: '',
}
export default function RootLayout({

View File

@ -1,7 +1,17 @@
import { getAllPosts } from "@/lib/posts"
import Link from "next/link";
export default function Home() {
const pages = getAllPosts(["title", "slug"]);
return (
<main className="">
Yo
<main>
{pages.map(page => (
<Link href={`/blog/${page.slug}`} key={page.title}>
{page.title}
</Link>
))}
</main>
)
}

40
lib/posts.ts Normal file
View File

@ -0,0 +1,40 @@
import fs from "fs"
import { join } from "path"
import matter from 'gray-matter'
const postsDirectory = join(process.cwd(), "posts");
export function getPostSlugs() {
const fileNames = fs.readdirSync(postsDirectory);
return fileNames.map(filename => filename.replace(/\.mdx$/, ""))
}
export function getPostBySlug(slug: string, fields: string[] = []) {
const fullPath = join(postsDirectory, `${slug}.mdx`);
const fileContents = fs.readFileSync(fullPath, "utf8");
const { data, content } = matter(fileContents)
type Items = {
[key: string]: string;
}
const items: Items = {};
fields.forEach((field) => {
if (field === "slug") {
items[field] = slug;
} else if (field === "content") {
items[field] = content;
} else if (typeof data[field] !== undefined) {
items[field] = data[field];
}
});
return items;
}
export function getAllPosts(fields: string[] = []) {
const slugs = getPostSlugs();
const posts = slugs.map((slug) => getPostBySlug(slug, fields));
return posts;
}

View File

@ -9,19 +9,23 @@
"lint": "next lint"
},
"dependencies": {
"react": "^18",
"react-dom": "^18",
"next": "14.0.4"
"gray-matter": "^4.0.3",
"next": "14.0.4",
"next-mdx-remote": "^4.4.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"remark": "^15.0.1",
"remark-html": "^16.0.1"
},
"devDependencies": {
"typescript": "^5",
"@types/node": "^20",
"@types/react": "^18",
"@types/react": "^18.2.8",
"@types/react-dom": "^18",
"autoprefixer": "^10.0.1",
"eslint": "^8",
"eslint-config-next": "14.0.4",
"postcss": "^8",
"tailwindcss": "^3.3.0",
"eslint": "^8",
"eslint-config-next": "14.0.4"
"typescript": "^5.1.3"
}
}

1497
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

5
posts/test-post.mdx Normal file
View File

@ -0,0 +1,5 @@
---
title: Test Post
---
# This is a test post