Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/thefubon/next15-mdx-blog
Next 15.0.3 | React 19.0.0 | TailwindCSS 3.4.14 | ESlint 9.14.0 | PNPM
https://github.com/thefubon/next15-mdx-blog
mdx mdx-blog next-blog next15 next15-mdx-blog nextjs15
Last synced: 2 days ago
JSON representation
Next 15.0.3 | React 19.0.0 | TailwindCSS 3.4.14 | ESlint 9.14.0 | PNPM
- Host: GitHub
- URL: https://github.com/thefubon/next15-mdx-blog
- Owner: thefubon
- Created: 2024-11-12T15:20:25.000Z (2 days ago)
- Default Branch: main
- Last Pushed: 2024-11-12T16:20:16.000Z (2 days ago)
- Last Synced: 2024-11-12T16:36:42.792Z (2 days ago)
- Topics: mdx, mdx-blog, next-blog, next15, next15-mdx-blog, nextjs15
- Language: TypeScript
- Homepage: https://next15-mdx-blog.fubon.ru
- Size: 205 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Next Blog
Next 15.0.3 | React 19.0.0 | TailwindCSS 3.4.14 | ESlint 9.14.0 | PNPM
- [x] Next 15
- [x] NDX Blog
- [ ] Tailwind 4[VIEW CHANGELOG](https://github.com/thefubon/next15-mdx-blog/blob/main/CHANGELOG.md)
### MDX Components
```mdx
```
## Install Package
```bash
pnpm i gray-matter next-mdx-remote path fs
```## Bug Fix: slug.params
```bash
npx @next/codemod@canary next-async-request-api . --force
```## Pages
Context MDX: `content/hello-world.mdx`
```mdx
---
title: "Hello World"
date: "2024-11-12"
description: "This is a sample MDX file."
---## This is a sample MDX file
This is a sample MDX file. It contains JSX and markdown content.
![Image](https://images.unsplash.com/photo-1730840669516-10f18020ca8e?w=800&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxmZWF0dXJlZC1waG90b3MtZmVlZHwyNnx8fGVufDB8fHx8fA%3D%3D)
```
Components: `components/mdx/youtube.tsx`
```tsx
const YouTube = ({ videoId }: { videoId: string }) => {
const videoSrc = `https://www.youtube.com/embed/${videoId}`
return (
)
}export default YouTube
```Blog List: `app/blog/page.tsx`
```tsx
import fs from 'fs'
import path from 'path'
import matter from 'gray-matter'
import Link from 'next/link'export default function Blog() {
const blogDirectory = path.join(process.cwd(), 'content')
const fileNames = fs.readdirSync(blogDirectory)const blogs = fileNames.map((fileName) => {
const slug = fileName.replace('.mdx', '')
const fullPath = path.join(blogDirectory, fileName)
const fileContents = fs.readFileSync(fullPath, 'utf8')const { data: frontMatter } = matter(fileContents)
const date = new Date(frontMatter.date)
// Отформатируйте дату в удобочитаемый строковый формат
// Например, "12 ноября 2024 г.".
const formattedDate = date.toLocaleDateString('ru-RU', {
year: 'numeric',
month: 'long',
day: 'numeric',
})return {
slug,
formattedDate,
meta: frontMatter,
}
})return (
{blogs.map((blog) => (
{blog.meta.title}
{blog.formattedDate}
{blog.meta.description}
))}
)
}```
Blog Post: `app/blog/[slug]/page.tsx`
```tsx
import fs from 'fs'
import path from 'path'
import matter from 'gray-matter'
import { MDXRemote } from 'next-mdx-remote/rsc'
import YouTube from '@/components/mdx/youtube'
import Link from 'next/link'async function getPost(slug: string) {
const markdownFile = fs.readFileSync(
path.join('content', `${slug}.mdx`),
'utf-8'
)
const { data: frontMatter, content } = matter(markdownFile)
return {
frontMatter,
slug,
content,
}
}export async function generateStaticParams() {
const files = fs.readdirSync(path.join('content'))
const params = files.map((filename) => ({
slug: filename.replace('.mdx', ''),
}))return params
}export default async function Page(url: { params: Promise<{ slug: string }> }) {
const params = await url.params
const { slug } = params
const props = await getPost(slug)// MDX Custom Components
const components = {
YouTube,
}return (
<>
Назад
{props.frontMatter.title}
{props.frontMatter.description}
>
)
}
```