- Published on
Blog 从 Hugo 迁移到 Tailwind Next.js Blog
- Authors
- Name
- ttyS3
https://github.com/timlrx/tailwind-nextjs-starter-blog
https://github.com/timlrx/pliny
Table of Contents
migration repo
git checkout -b hugo
git push origin hugo
git branch -D main
git checkout --orphan main
rm -rf ./*
rm -rf .forestry .gitignore .gitmodules
cp -rav ~/repo/blog/nextjs-ttys3.dev/* .
cp -rav ~/repo/blog/nextjs-ttys3.dev/.* .
meld . ~/repo/blog/nextjs-ttys3.dev
bcompare . ~/repo/blog/nextjs-ttys3.dev
git remote add origin [email protected]:ttys3/ttys3.dev.git
git push origin main -f
Guide to MDX
https://kabartolo.github.io/chicago-docs-demo/docs/mdx-guide/
netlify related
build Failed
plugin "@netlify/plugin-nextjs" failed
Error: The directory "/opt/build/repo/public" does not contain a Next.js production build. Perhaps the build command was not run, or you specified the wrong publish directory. However, a '.next' directory was found with a production build. Consider changing your 'publish' directory to '.next' If you are using "next export" then you should set the environment variable NETLIFY_NEXT_PLUGIN_SKIP to "true".
Build configuration
Runtime Next.js
Build command npm run build
fixup:
change Publish directory public
=> Publish directory .next
Next.js integrations
https://docs.netlify.com/integrations/frameworks/#next-js
Node.js environment
https://docs.netlify.com/configure-builds/manage-dependencies/#node-js-environment
Next.js on Netlify
https://docs.netlify.com/integrations/frameworks/next-js/overview/
Troubleshooting Next.js on Netlify
https://docs.netlify.com/integrations/frameworks/next-js/troubleshooting/
troubleshoot
.md
to .mdx
rename
1. rnr -r -f '.md' '.mdx' .
rnr -r -f '.mdxx' '.mdx' .
2. markdown link compitable with MDX
❯ rg '<http(s)?://.+?>' -l | wc -l
70
neither Rust or Golang Regex engine support look around (look ahead or look after)
we need use a tool support PCRE like https://github.com/adamreisnz/replace-in-file
npm i -g replace-in-file
debug the Regex : https://regex101.com/r/9UPYQr/1
config.js
content:
//config.js
module.exports = {
files: './**/*.mdx',
from: /(?<!\])<http(s)?:\/\/([^[\]]+?)>(?!\])/g,
to: ' http\$1://\$2 ',
};
replace-in-file --configFile=config.js
remove not used frontmatter fields:
# check
rg '^slug:\s+[a-zA-Z_-]+'
# delete
sed -E -i '/^slug:\s+[a-zA-Z_-]+/d' `rg -l slug`
3. null-safe join of tags
commit baab006f840d07fe5a1ea27a6c586a118d21870c
Author: ttyS3 <[email protected]>
Date: 2023-07-10 20:31:17 +0800
chore: null-safe join of tags
diff --git a/layouts/ListLayout.tsx b/layouts/ListLayout.tsx
index fb967f7..7c94a9d 100644
--- a/layouts/ListLayout.tsx
+++ b/layouts/ListLayout.tsx
@@ -66,7 +66,7 @@ export default function ListLayout({
}: ListLayoutProps) {
const [searchValue, setSearchValue] = useState('')
const filteredBlogPosts = posts.filter((post) => {
- const searchContent = post.title + post.summary + post.tags.join(' ')
+ const searchContent = post.title + post.summary + (post.tags ?? []).join(' ')
return searchContent.toLowerCase().includes(searchValue.toLowerCase())
})
@@ -129,7 +129,7 @@ export default function ListLayout({
</Link>
</h3>
<div className="flex flex-wrap">
- {tags.map((tag) => (
+ {(tags ?? []).map((tag) => (
<Tag key={tag} text={tag} />
))}
</div>
diff --git a/layouts/PostLayout.tsx b/layouts/PostLayout.tsx
index 0562fd9..c5b165c 100644
--- a/layouts/PostLayout.tsx
+++ b/layouts/PostLayout.tsx
@@ -123,7 +123,7 @@ export default function PostLayout({ content, authorDetails, next, prev, childre
Tags
</h2>
<div className="flex flex-wrap">
- {tags.map((tag) => (
+ {(tags ?? []).map((tag) => (
<Tag key={tag} text={tag} />
))}
</div>
diff --git a/pages/index.tsx b/pages/index.tsx
index f8fafeb..c084f88 100644
--- a/pages/index.tsx
+++ b/pages/index.tsx
@@ -57,7 +57,7 @@ export default function Home({ posts }: InferGetStaticPropsType<typeof getStatic
</Link>
</h2>
<div className="flex flex-wrap">
- {tags.map((tag) => (
+ {(tags ?? []).map((tag) => (
<Tag key={tag} text={tag} />
))}
</div>
diff --git a/pages/tags/[tag].tsx b/pages/tags/[tag].tsx
index f939fc6..4437f40 100644
--- a/pages/tags/[tag].tsx
+++ b/pages/tags/[tag].tsx
@@ -23,7 +23,7 @@ export const getStaticProps = async (context) => {
const tag = context.params.tag as string
const filteredPosts = allCoreContent(
allBlogs.filter(
- (post) => post.draft !== true && post.tags.map((t) => kebabCase(t)).includes(tag)
+ (post) => post.draft !== true && (post.tags ?? []).map((t) => kebabCase(t)).includes(tag)
)
)
3. build problem
❯ npm run build
Failed to compile.
./pages/404.tsx
9:36 Error: Replace `t-6·pb-8` with `b-8·pt-6` prettier/prettier
solution:
❯ npm run lint
> [email protected] lint
> next lint --fix --dir pages --dir components --dir lib --dir layouts --dir scripts
the fixup like:
diff --git a/pages/404.tsx b/pages/404.tsx
index 2bdf448..873137d 100644
--- a/pages/404.tsx
+++ b/pages/404.tsx
@@ -6,7 +6,7 @@ export default function FourZeroFour() {
<>
<PageSEO title="Page Not Found" description="Sorry we couldn't find this page :(" />
<div className="flex flex-col items-start justify-start md:mt-24 md:flex-row md:items-center md:justify-center md:space-x-6">
- <div className="space-x-2 pt-6 pb-8 md:space-y-5">
+ <div className="space-x-2 pb-8 pt-6 md:space-y-5">
<h1 className="text-6xl font-extrabold leading-9 tracking-tight text-gray-900 dark:text-gray-100 md:border-r-2 md:px-6 md:text-8xl md:leading-14">
404
</h1>
empty tags still cause problem:
λ (Server) server-side renders at runtime (uses getInitialProps or getServerSideProps)
○ (Static) automatically rendered as static HTML (uses no initial props)
● (SSG) automatically generated as static HTML + JSON (uses getStaticProps)
(node:825002) ExperimentalWarning: Importing JSON modules is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
RSS feed generated...
Sitemap generated...
file:///home/user001/repo/blog/ttys3.dev/node_modules/pliny/utils/generate-rss.js:43
(post) => post.tags.map((t) => GithubSlugger.slug(t)).includes(tag)
^
TypeError: Cannot read properties of undefined (reading 'map')
at file:///home/user001/repo/blog/ttys3.dev/node_modules/pliny/utils/generate-rss.js:43:29
at Array.filter (<anonymous>)
at generateRSS (file:///home/user001/repo/blog/ttys3.dev/node_modules/pliny/utils/generate-rss.js:42:38)
workaround:
edit contentlayer.config.ts
set a default value for tags
:
diff --git a/contentlayer.config.ts b/contentlayer.config.ts
index 3f6c2b8..929806e 100644
--- a/contentlayer.config.ts
+++ b/contentlayer.config.ts
@@ -44,7 +44,7 @@ export const Blog = defineDocumentType(() => ({
fields: {
title: { type: 'string', required: true },
date: { type: 'date', required: true },
- tags: { type: 'list', of: { type: 'string' } },
+ tags: { type: 'list', of: { type: 'string' }, default: [] },
lastmod: { type: 'date' },
draft: { type: 'boolean' },
summary: { type: 'string' },
ref contentlayer list
page bundle image support
currently does not support page bundle images, see
https://github.com/timlrx/pliny/issues/106
npm install git+https://github.com/ttys3/remark-copy-linked-files.git
ref to https://unifiedjs.com/learn/guide/create-a-plugin/#plugin-basics
and https://mdxjs.com/docs/extending-mdx/#components--plugins
mainly hack:
dataDir
is default to data
// path is something like `/path-to-project-root/_mdx_bundler_entry_point-3e814d53-72fb-474b-8853-f64f1521e36a.mdx`
// after contentlayer (which uses mdx-bundler)
// `file.data.rawDocumentData.sourceFilePath` begin with `blog/xxx`, does not include the `data` dir
const fullpath = resolve(
cwd,
dataDir,
file?.data?.rawDocumentData?.sourceFilePath ? dirname(file.data.rawDocumentData.sourceFilePath) : '',
platformNormalizedUrl,
);
and edit contentlayer.config.ts
, add to top:
import remarkCopyLinkedFiles from 'remark-copy-linked-files'
under remarkPlugins
, add below before remarkGfm
:
[remarkCopyLinkedFiles, {destinationDir: process.cwd() +"/public/static/images/blog/", staticPath: "/static/images/blog"}],
other ref:
Netlify
https://docs.netlify.com/configure-builds/manage-dependencies/#pnpm
Netlify supports pnpm for Node.js 16.9.0 and later.
If your site’s base directory includes a pnpm-lock.yaml file, we will run pnpm install to install the dependencies listed in your package.json.
To specify a pnpm version, you can edit your package.json file:
"packageManager": "[email protected]"
This tells Corepack to use and download your preferred pnpm version instead of the default version that Netlify sets.
In certain scenarios, you must pass additional flags to the pnpm install command. For example, some frameworks such as Nuxt 3 and Next.js require that you modify the pnpm install command. To avoid import issues with pnpm and these frameworks, use the PNPM_FLAGS
environment variable and set it to --shamefully-hoist
. Learn more in our Nuxt docs and Next.js docs.
https://docs.netlify.com/integrations/frameworks/next-js/overview/#pnpm-support
pnpm support If you’re planning to use pnpm with Next.js to manage dependencies, you must do one of the following:
Set a PNPM_FLAGS
environment variable with a value of --shamefully-hoist
. This appends a --shamefully-hoist
argument to the pnpm install command that Netlify runs.
Enable public hoisting by adding an .npmrc file in the root of your project with this content:
public-hoist-pattern[]=*