内容运营工具
后台内置的日常运营工具:导航菜单、草稿预览链接、自动备份、站内搜索、图片优化、自定义内容类型、作者与投稿者角色和表单。
导航菜单
后台 → 内容 → 导航菜单(/admin/menus,仅管理员)维护网站的页头、页脚等导航,不用改代码,保存后立即生效。
- 每个菜单有一个位置(
primary= 页头主导航,footer= 页脚链接,也可以自定义)和语言,每种语言一份;新建时可以从另一份复制。 - 菜单项可以是页面、文章、产品、文章分类、产品分类或自定义链接(
/about、https://…、#锚点、mailto:);javascript:等不安全链接会被拒绝。 - 拖动调整顺序,用按钮设为子菜单或移出,最多三级;可设置新窗口打开。
- 指向的内容改了别名会自动跟随;未发布或已删除的内容不会出现在菜单里。
框架默认布局:存在 primary 菜单时页头使用它(有子菜单的项显示为下拉,父项本身的链接在下拉第一项),存在 footer 菜单时页脚「公司」一栏使用它;没有菜单时保持原来的导航。站点自己的布局用组合式函数读取:
const { items } = useMenu('primary') // 没有该菜单时为 null
// items: [{ id, label, to, external, newTab, children: [...] }]
接口:GET /api/public/menus/:key?locale=zh(公开缓存,保存菜单时自动清除)。
草稿预览链接
在文章、页面或产品的编辑页点击预览链接,生成一个 1 / 7 / 30 天内有效的链接,发给客户或同事,对方无需后台账号就能用网站正式的页面样式查看这篇未发布的内容。
- 打开链接后浏览器记住预览状态,页面底部显示「预览模式」提示,可随时退出。
- 只放开这一篇内容;预览请求不经过缓存,并带
noindex,不会被搜索引擎收录。 - 链接使用由
NUXT_JWT_SECRET派生的密钥签名,无法伪造或改成别的内容;到期自动失效。 - 自定义了编辑器(ContentEditor)的站点加上
<ContentPreviewLink v-if="id" :kind="type" :ref-id="id" />即可(nuxtcms doctor会提示);覆盖了公开详情接口的站点需要自行使用publishedOrPreview()。
自动备份
后台 → 系统 → 自动备份(/admin/backups,仅管理员):
- 每天或每周在指定时间(站点时区)备份一次,也可以随时立即备份;保留最近 N 份,更早的自动删除。
- 备份位置可多选:
- 附件存储(R2 / OSS / COS / S3 / 本地):存放在
private/backups/,不会公开访问,可在备份记录中下载; - 存储桶(与网站附件分开的独立备份桶):Cloudflare R2、AWS S3、阿里云 OSS、腾讯云 COS,或任何 S3 兼容存储(MinIO、Backblaze B2 等,填写 Endpoint)。填写存储桶名称、地域、Access Key 和目录,可先测试连接(写入、列出、删除一个测试文件);密钥加密保存,目录里只保留最近 N 份。建议为备份单独创建一个只能读写该桶的密钥。
- FTP 服务器:填写主机、端口、用户名、密码和目录(不存在会自动创建),支持 FTPS(AUTH TLS),可先测试连接。密码加密保存。
- 附件存储(R2 / OSS / COS / S3 / 本地):存放在
- 备份文件是
.json.gz,内容与「工具 → 导出」相同:文章、页面、产品、分类、翻译、公开设置和媒体列表,可在「工具 → 导入」中恢复。不含账号、密钥、附件文件本身和插件数据(订单等)——这些请另行备份数据库(Cloudflare D1 自带 30 天时间点恢复)。 - 定时备份由定时任务 Worker 触发(
/api/cron/dispatch,需要NUXT_CRON_SECRET);没有配置时只能手动备份。 - Cloudflare 上通过 TCP Socket 连接 FTP。要求 TLS 会话复用的 FTPS 服务器(如 vsftpd 的
require_ssl_reuse=YES)只能从 Node 部署连接,或在服务器上关闭该选项。
站内搜索
访客在 /search?q=关键词(框架默认页头有搜索按钮)搜索当前语言已发布的文章、页面和产品:
- 多个词之间是「并且」,
"带引号的词组"整体匹配;标题命中排在前面,结果显示命中处的摘要并高亮。 - 子串匹配,中文不需要分词;SQLite / D1、PostgreSQL、MySQL 行为一致。
- 内容保存、发布、撤回、删除时索引自动更新;升级前的内容由定时任务每次补 200 条,也可以在 工具 → 站内搜索索引 立即重建。
- 接口
GET /api/search?q=&locale=&kind=post|page|product&limit=(不经过公开缓存,每个 IP 每分钟 60 次)。
图片优化
在后台上传图片(媒体库、选择图片、编辑器里粘贴或拖入)时,浏览器先处理再上传,服务器不做图片运算(适合边缘环境的 CPU 限制):
- 超过 2560 像素或 200 KB 的 JPEG / PNG / WebP 会缩到最长边 2560 像素并转为 WebP(体积更小时才替换,原始 GIF、SVG 和小图不变),手机照片按 EXIF 方向摆正;
- 同时生成 480 像素的 WebP 预览图,媒体库和选择图片窗口用它显示,加载更快;
- 媒体库可以填写替代文本(Alt),记录图片尺寸。
压缩后上传上限仍是 5 MB(几十 MB 的原图也能先压缩再上传)。
先显示中等清晰度,再显示高清
照片上传时还会生成一张中等清晰度的副本(最长边 1024 像素,WebP),只有比原图明显更小时才保留。前台页面在服务器输出时先用中等图(体积通常只有原图的十分之一到三分之一),页面加载完、图片进入可视区域后再换成高清原图;离可视区域还远的图片仍按需加载。后台页面不受影响。
- 以前上传的图片:媒体库右上角点 生成中等清晰度图片,在浏览器里逐张补做。
- 模板自带的静态图(站点
public/目录,比如首页大图):在本机运行npx nuxtcms images(需要sharp,或在 nuxtcms 仓库里运行node scripts/cli.mjs images --dir <站点目录>),生成public/_mid/和清单,提交后部署。 - 关闭:环境变量
NUXT_PROGRESSIVE_IMAGES=false。nuxt dev下不生效(避免开发时的 hydration 提示)。
自定义内容类型
「后台 → 内容 → 内容类型」可以不写代码新建自己的内容,例如客户案例、团队成员、常见问题、活动。可以从预设开始,也可以自己加字段:
- 字段类型:单行文本、多行文本、富文本、数字、开关、日期、图片、多图、链接、下拉选项、列表;可设为必填;
- 每个类型在侧边栏「内容」下有自己的菜单项,条目有草稿 / 发布 / 定时发布、历史版本和多语言;
- 设为公开后,默认页面
/<语言>/c/<标识>列出条目,/<语言>/c/<标识>/<slug>显示单条,并进入站点地图和站内搜索;不公开的类型只供站点代码读取; - 站点代码:
useCollection('cases')、useCollectionItem('cases', slug),或GET /api/public/collections/:key、/api/public/collections/:key/:slug;字段值用<CmsFieldValue>显示; - 删除类型需要输入它的标识确认,条目一并删除。
作者与投稿者
「后台 → 用户」除管理员和编辑外还有两个角色:
| 角色 | 可以做什么 |
|---|---|
| 管理员 | 全部,包括设置、用户、插件和安全 |
| 编辑 | 所有文章、页面、产品、内容类型和媒体 |
| 作者 | 撰写并发布自己的文章,可以上传图片 |
| 投稿者 | 撰写自己的文章,只能保存为草稿,由编辑审核发布;只能选用已有图片 |
作者和投稿者看不到其他菜单,服务端也只允许他们调用文章、媒体、预览和自己账户的接口(插件接口也不行),并且只能打开和修改自己的文章。
多用户与找回密码(需要先在「邮件设置」配置发信邮箱):
- 新建用户时可以勾选「发送邀请邮件」,不用替对方设密码:对方收到链接(3 天内有效)后自己设置密码。
- 用户列表的安全菜单里可以「发送重置密码邮件」。
- 登录页有「忘记密码?」:输入后台邮箱即可收到重置链接(1 小时内有效、只能用一次)。无论邮箱是否存在都显示同样的结果,按 IP 和邮箱限流,并使用登录场景的人机验证。重置后该用户所有设备需要重新登录。
- 链接不在数据库里保存:令牌里含当前密码的指纹,改过密码后旧链接自动失效。
表单
「后台 → 内容 → 表单」可以搭建询价单、报名表、问卷等:
- 字段:单行文本、邮箱、电话、多行文本、数字、下拉、单选、多选、日期、同意勾选框;每种语言可以有自己的字段名称;
- 在页面或文章正文里单独一行写
[form 表单标识]即显示该表单(列表里的代码按钮可复制),站点代码里用<CmsForm form="表单标识" />; - 提交时服务端再次校验,按访客 IP 限流(每表单 10 分钟 5 次),可开启验证码(使用「安全」里的“联系表单”场景);
- 提交记录保存在后台,可标为已读、归档、删除和导出 CSV(Excel 可直接打开,公式单元格已转义);可填写通知邮箱,每次提交发邮件;
- 每次提交触发
form.submitted事件,机器人通知、Webhook 插件可以转发到企业微信、钉钉、飞书等; - 关闭的表单不再接受提交。
测试
pnpm smoke:content --base http://localhost:3192 覆盖菜单(未发布内容隐藏、缓存清除、不安全链接)、预览链接(签名、篡改、只放开一篇、不缓存)、备份(附件存储与 FTP、轮换、下载权限、不含密钥;脚本自带一个模拟 FTP 服务器)、站内搜索(只含已发布内容、语言与类型筛选、排序、撤回后移除)、媒体(预览图、Alt、删除时一并删除预览)、内容类型(字段校验、草稿与发布、搜索、公开与否)、角色(作者 / 投稿者的权限边界)和表单(校验、提交、CSV、关闭)。