使用Next.js创建Blog( 二 )

{post.title}{post.tags.map((tag) => {return ()})})})})})})}export default IndexPageexport async function getStaticProps() {const {GetAllPosts} = await import('utils/getAllPosts')const posts = await GetAllPosts()const groupByMonthPosts = posts.reduce((prev, next) => {if (Array.isArray(prev[next.group])) {prev[next.group].push(next)} else {prev[next.group] = []prev[next.group].push(next)}return prev}, {})return {props: {groupByMonthPosts}}}复制代码

  1. 创建pages/[...slug].tsx
import {MDXRemote} from 'next-mdx-remote'import {serialize} from 'next-mdx-remote/serialize'import dynamic from 'next/dynamic'import ErrorPage from 'next/error'import NextLink from 'next/link'import {useRouter} from 'next/router'import React from 'react'import remarkGfm from 'remark-gfm'import components from 'utils/components'import {Container,Box,Heading,Text,Link,Image,Center} from '@chakra-ui/react'const PostPage = dynamic(() => import('components/PostPage'))const Post = ({title, description, date, originalUrl, mdxSource, cover}) => {const router = useRouter()if (!router.isFallback && !mdxSource) {return <ErrorPage statusCode={404} />}return (<Containermt={20}maxW={{sm: 'container.sm',md: 'container.md',lg: 'container.2xl',xl: 'container.xl'}}className="post"><NextSeotitle={title}description={description}openGraph={{title, description}}/><Box as="hgroup"><Text textAlign="center" color="gray.500" fontSize="xs" as="p">Published {date}</Text><Heading textAlign="center" as="h1" mt={4} mb={2}>{title}</Heading>{originalUrl && (<Center color="gray.500" fontSize="sm" mb={8}>本文翻译自:<NextLink legacyBehavior href=https://www.isolves.com/it/cxkf/kj/2022-11-25/{originalUrl} passHref>{originalUrl})})}export const getStaticPaths = async () => {const {GetAllPosts} = await import('utils/getAllPosts')const allPosts = await GetAllPosts()const paths = allPosts.map((post) => ({params: {slug: post.slug.split('/')}}))return {paths,fallback: false}}export const getStaticProps = async ({params}) => {const {GetPostBySlug} = await import('utils/getAllPosts')const {content, ...data} = await GetPostBySlug(params.slug)const mdxSource = await serialize(content, {mdxOptions: {remarkPlugins: [[remarkGfm]],rehypePlugins: []},scope: data})return {props: {...data,mdxSource}}}export default Post复制代码至此,基本框架搭建完成,接下来调整样式及组件的引入,以及 mdx 渲染修正 。
  1. 调整样式
可选
引入tailwind.css,执行pnpm install -D tailwindcss postcss autoprefixer && npx tailwindcss init -p
修改tailwind.config.js,如下:
/** @type {import('tailwindcss').Config} */module.exports = {content: ['./pages/**/*.{js,ts,jsx,tsx}','./components/**/*.{js,ts,jsx,tsx}'],theme: {extend: {}},plugins: []}复制代码修改全局样式styles/globals.scss
@tailwind base;@tailwind components;@tailwind utilities;复制代码必须
修改pages/_app.tsx,引入chakra-ui的配置
// pages/_app.jsimport {ChakraProvider} from '@chakra-ui/react'function MyApp({Component, pageProps}) {return (<ChakraProvider><Component {...pageProps} /></ChakraProvider>)}export default MyApp复制代码到这里,不出意外,你的界面应该是长这样
使用Next.js创建Blog

文章插图
 
点击链接,应该会报错,未引入utils/components,这个是配置 mdx 内元素渲染的组件,参考MDX Components,mdx 提供默认的渲染组件,所以,这个是非必须的,不需要删除即可
个人比较喜欢 chakra-ui,所以将组件都转成了 chakra-ui 提供的组件,配置如下:
import CanIUse from 'components/CanIUse'import {Heading, Link, Box} from '@chakra-ui/react'import {FiExternalLink} from 'react-icons/fi'const components = {CanIUse,h2: (props) => (<Heading as="h2" mb={4}>{props.children}</Heading>),h3: (props) => (<Heading as="h3" mb={4}>{props.children}</Heading>),h4: (props) => (<Heading as="h4" mb={4}>{props.children}</Heading>),h5: (props) => (<Heading as="h5" mb={4}>{props.children}</Heading>),p: (props) => (<Box as="div" mb={4}>{props.children}</Box>),div: (props) => <Box mb={4}>{props.children}</Box>,a: (props) => {return (<Linkdisplay="inline-flex"alignItems="center"href=https://www.isolves.com/it/cxkf/kj/2022-11-25/{props.href}gap={2}isExternal>{props.children}


推荐阅读