Next.js中手动配置netlify-cms
Netlify-CMS是一个很好用的CMS系统,开源且免费,经常与Next.js、Hugo、Nuxt.js等静态网站生成工具一起使用。在Next.js项目中启用netlify-cms是比较简单的,但是如果要做一些自定义插件设置,就会稍微复杂一些。
先看官方的配置:
官方配置
要在Next.js中启用netlify-cms,只需要在静态文件目录中添加一个admin目录,里面放一个index.html和config.yml即可。这部分可以直接看netlify-cms的官方文档:
1 2 3
admin ├ index.html └ config.yml
对于Next.js来说,静态文件目录在public目录,所以只要在public目录中建立一个admin子目录,并按上面的方式添加index.html和config.yml即可。
index.html(复制即可):
1 2 3 4 5 6 7 8 9 10 11 12
<!doctype html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Content Manager</title> </head> <body> <!-- Include the script that builds the page and powers Netlify CMS --> <script src="https://unpkg.com/netlify-cms@^2.0.0/dist/netlify-cms.js"></script> </body> </html>
config.yml(按需调整):
1 2 3
backend: name: git-gateway branch: master # Branch to update (optional; defaults to master)
这种方式可以应对大部分场景,但是在注册自定义插件的时候不是很方便。
Next.js中动态渲染
如果不使用静态文件的方式,而改成动态渲染。就会需要在Next.js项目的 src/pages/
目录中新建一个admin.tsx
或admin.jsx
文件,并完成相应的渲染。
官方文档中也有一部分示例:
npm install netlify-cms-app --save
1 2 3 4 5
import CMS from 'netlify-cms-app' // Initialize the CMS object CMS.init() // Now the registry is available via the CMS object. CMS.registerPreviewTemplate('my-template', MyTemplate)
但是在next.js中直接复制上述代码的话,会报一个错误:window is not defined.
,因为next.js有服务端渲染的部分,而netlify-cms-app
的内部有对window的处理,不兼容ssr,所以会报错。
Github上有一个开源项目jakeprins/nextjs-netlify-cms,提供了一个解决方案。
1 2 3 4 5 6 7 8 9 10 11 12 13
import dynamic from 'next/dynamic'; import config from '../cms/config'; const CMS = dynamic( () => import('netlify-cms-app').then((cms) => { cms.init({ config }); }), { ssr: false, loading: () => <p>Loading...</p> } ); const AdminPage: React.FC = () => { return <CMS />; }; export default AdminPage;
实际操作过程中,我发现它会有一个白屏的问题,所以还需要微调一下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
import dynamic from 'next/dynamic'; import config from './config.json' const CMS = dynamic( () => import('netlify-cms-app').then(async (cms: any) => { cms.init({ config }); }) as any, { ssr: false, loading: () => <p>Loading...</p> } ); const AdminPage: React.FC = () => { return <> <div id='nc-root' /> <CMS /> </> }; export default AdminPage;
在这里,就可以注册自定义插件了。注意如果你的自定义插件中引用了netlify-cms中的东西,则可能也需要使用dynamic import技术,取代文件头部引入的方式。
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
import dynamic from 'next/dynamic'; import config from './config.json' const CMS = dynamic( () => import('netlify-cms-app').then(async (cms: any) => { const { HtmlControl, HtmlPreview } = await import('netlify-cms-widget-html') cms.init({ config }); cms.registerWidget('html', HtmlControl, HtmlPreview) }) as any, { ssr: false, loading: () => <p>Loading...</p> } ); const AdminPage: React.FC = () => { return <> <div id='nc-root' /> <CMS /> </> }; export default AdminPage;
以上。