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