nextjs-tinacms
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseNext.js 16 + React 19 + TinaCMS Skill
Next.js 16 + React 19 + TinaCMS 技能指南
Two primary workflows:
- New Project: Scaffold Next.js 16 + TinaCMS with blocks page builder, visual editing, complete SEO, Tailwind CSS 4, shadcn/ui
- Add CMS: Integrate TinaCMS into an existing Next.js 15/16 project
两种核心工作流:
- 新项目搭建:初始化带有区块页面构建器、可视化编辑、完整SEO、Tailwind CSS 4、shadcn/ui的Next.js 16 + TinaCMS项目
- 集成CMS:将TinaCMS整合到现有Next.js 15/16项目中
Why This Stack
技术栈优势
- Next.js 16 — Turbopack default, directive,
"use cache"replaces middleware, async params required, React 19.2proxy.ts - TinaCMS 3.x — Git-backed headless CMS, visual click-to-edit, GraphQL API from code-first schema, admin UI at
/admin - React 19.2 — Server Components stable, Actions, hook, View Transitions, React Compiler (opt-in)
use() - Tailwind CSS 4 — CSS-first config, , no
@import "tailwindcss"neededtailwind.config.js - shadcn/ui — Copy-paste components, works with Tailwind, not a versioned package
- Next.js 16 — 默认使用Turbopack,支持指令,
"use cache"替代middleware,强制要求异步参数,搭配React 19.2proxy.ts - TinaCMS 3.x — 基于Git的无头CMS,支持可视化点击即编辑,通过代码优先Schema生成GraphQL API,管理后台入口为
/admin - React 19.2 — Server Components稳定可用,支持Actions、钩子、View Transitions,可选启用React Compiler
use() - Tailwind CSS 4 — CSS优先配置模式,支持,无需
@import "tailwindcss"文件tailwind.config.js - shadcn/ui — 可直接复制粘贴的组件库,兼容Tailwind,非版本化包
Critical Knowledge
关键注意事项
- Server-Client split is mandatory. requires
useTina(). Every editable page needs a Server Component (data fetcher) and a Client Component (visual editing wrapper). No global"use client"needed in TinaCMS v2+.TinaProvider - Build order matters. Always . Running
"build": "tinacms build && next build"first →next build.Cannot find module '../tina/__generated__/client' - Pin exact TinaCMS versions. No caret ranges. UI assets partially served from CDN and drift from local CLI. Keep all and
tinacmssynced via RenovateBot grouping.@tinacms/* - MUST be committed. Files
tina/__generated__/,_graphql.json,_lookup.json, and_schema.jsonare needed for production builds.tina-lock.json - Async params in Next.js 16. Every ,
page.tsx,layout.tsxmustroute.ts— sync access fully removed.await params - replaces
proxy.tsin Next.js 16. Auth, redirects, and request manipulation move tomiddleware.tsrunning on Node.js runtime.app/proxy.ts - Node.js ≥ 20.9.0 required. Next.js 16 dropped Node 18.
- Field names: alphanumeric + underscores only. Hyphens/spaces in schema field names cause build errors.
- pnpm required for TinaCMS ≥ 2.7.3. npm/yarn may have module resolution issues.
- Dev command is . Never
tinacms dev -c "next dev"alone — the local GraphQL server won't run.next dev - Self-hosted TinaCMS does NOT work in Edge Runtime (Cloudflare Workers, Vercel Edge Functions). Marked wontfix.
- returns props.data unchanged in production — zero overhead. Only subscribes to live updates in edit mode.
useTina()
- 必须严格区分服务端与客户端组件。要求添加
useTina()指令。每个可编辑页面都需要一个服务端组件(数据获取器)和一个客户端组件(可视化编辑包装器)。TinaCMS v2+无需全局"use client"。TinaProvider - 构建顺序至关重要。构建命令必须为。若先执行
"build": "tinacms build && next build"会导致next build错误。Cannot find module '../tina/__generated__/client' - 固定TinaCMS精确版本。禁止使用 caret 范围(^)。UI资源部分从CDN加载,可能与本地CLI版本不一致。通过RenovateBot分组同步所有和
tinacms包版本。@tinacms/* - 必须提交目录。其中的
tina/__generated__/、_graphql.json、_lookup.json和_schema.json文件是生产构建必需的。tina-lock.json - Next.js 16的异步参数。所有、
page.tsx、layout.tsx必须使用route.ts——同步访问已被完全移除。await params - Next.js 16中替代
proxy.ts。认证、重定向和请求处理逻辑迁移至运行在Node.js runtime的middleware.ts。app/proxy.ts - 要求Node.js ≥ 20.9.0。Next.js 16已放弃对Node 18的支持。
- 字段名称仅允许字母数字+下划线。Schema字段名称中的连字符/空格会导致构建错误。
- TinaCMS ≥ 2.7.3要求使用pnpm。npm/yarn可能存在模块解析问题。
- 开发命令为。绝对不能单独执行
tinacms dev -c "next dev"——否则本地GraphQL服务器无法启动。next dev - 自托管TinaCMS无法在Edge Runtime中运行(Cloudflare Workers、Vercel Edge Functions),该问题标记为 wontfix。
- 生产环境中返回的props.data保持不变——无额外性能开销。仅在编辑模式下订阅实时更新。
useTina()
Version Floors
最低版本要求
Before scaffolding, look up current stable versions (). Minimum floors:
npm view <pkg> version| Package | Minimum | Why |
|---|---|---|
| ≥ 16.0.10 | Security patches |
| ≥ 3.3.x | Visual selector, current schema API |
| ≥ 2.1.x | Current build toolchain |
| ≥ 19.2.x | View Transitions, useEffectEvent |
| ≥ 4.x | CSS-first config (v3.4.x also acceptable) |
| Node.js | ≥ 20.9.0 | Next.js 16 requirement |
| TypeScript | ≥ 5.1.0 | Required for Next.js 16 types |
初始化项目前,查询当前稳定版本()。最低版本要求:
npm view <pkg> version| 包名 | 最低版本 | 原因 |
|---|---|---|
| ≥ 16.0.10 | 安全补丁 |
| ≥ 3.3.x | 可视化选择器、当前Schema API |
| ≥ 2.1.x | 当前构建工具链 |
| ≥ 19.2.x | View Transitions、useEffectEvent |
| ≥ 4.x | CSS优先配置(v3.4.x也可兼容) |
| Node.js | ≥ 20.9.0 | Next.js 16要求 |
| TypeScript | ≥ 5.1.0 | Next.js 16类型定义要求 |
Workflow: New Project
工作流:新项目搭建
Follow the 247-task checklist in task-by-task. The sections below summarize the architecture — the checklist has the exhaustive implementation details.
references/day0-2-checklist.md严格按照中的247项任务清单逐步执行。以下内容为架构概述——详细实现步骤请参考任务清单。
references/day0-2-checklist.mdStep 1: Scaffold & Install
步骤1:项目初始化与安装
bash
npx create-next-app@latest my-site --typescript --tailwind --app --src-dir --turbopack
cd my-site
npx @tinacms/cli@latest initVerify: → confirm loads at .
tinacms dev/adminhttp://localhost:3000/admin/index.htmlbash
npx create-next-app@latest my-site --typescript --tailwind --app --src-dir --turbopack
cd my-site
npx @tinacms/cli@latest init验证:执行 → 确认可加载管理后台。
tinacms devhttp://localhost:3000/admin/index.htmlStep 2: Configure Package Management
步骤2:包管理配置
Pin exact TinaCMS versions. Add — see for config.
renovate.jsonreferences/day0-2-checklist.md § Stack Versions固定TinaCMS精确版本。添加文件——配置示例请参考。
renovate.jsonreferences/day0-2-checklist.md § 技术栈版本Step 3: Schema Design in tina/config.ts
tina/config.ts步骤3:tina/config.ts
中的Schema设计
tina/config.tsRead for full examples. Use as starting point.
references/nextjs16-react19-tinacms-reference.md § Schema Design Patternstemplates/tina-config-starter.tsRequired collections:
| Collection | Type | Purpose |
|---|---|---|
| Folder + blocks | Dynamic pages with visual page builder |
| Folder | Blog/articles with structured fields |
| Folder | Referenced by posts |
| Single doc | Site-wide settings, SEO defaults, social links |
| Single doc | Editable nav structure |
| Single doc | Footer content and link groups |
| Single doc | Customizable 404 page content |
Singleton pattern:
typescript
ui: { global: true, allowedActions: { create: false, delete: false } }Blocks pattern:
typescript
{
type: 'object', list: true, name: 'blocks', label: 'Page Sections',
ui: { visualSelector: true },
templates: [heroBlock, featuresBlock, contentBlock, ctaBlock, faqBlock],
}Every block template needs: , , section style group (layout/background/height/textColor as enums mapped to Tailwind classes).
ui.previewSrcui.defaultItemField quality — enforce on every field:
- on title fields,
isTitle: trueon mandatory fieldsrequired: true - for character limits, format validation
ui.validate - for editorial guidance
ui.description - on every list field with meaningful labels
ui.itemProps - on multi-line strings,
ui.component: 'textarea'for collapsible groups'group'
Reusable field groups — extract as shared variables: , , , , .
seoFieldsctaFieldslinkFieldsresponsiveImageFieldssectionStyleFieldsContent hooks:
typescript
ui: {
beforeSubmit: async ({ values }) => ({
...values,
slug: values.title.toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, ''),
modifiedDate: new Date().toISOString(),
}),
}完整示例请参考。以为初始模板。
references/nextjs16-react19-tinacms-reference.md § Schema设计模式templates/tina-config-starter.ts必需集合:
| 集合名称 | 类型 | 用途 |
|---|---|---|
| 文件夹+区块 | 支持可视化页面构建器的动态页面 |
| 文件夹 | 带有结构化字段的博客/文章 |
| 文件夹 | 文章引用的作者信息 |
| 单文档 | 站点全局设置、SEO默认值、社交链接 |
| 单文档 | 可编辑的导航结构 |
| 单文档 | 页脚内容和链接组 |
| 单文档 | 可自定义的404页面内容 |
单例模式:
typescript
ui: { global: true, allowedActions: { create: false, delete: false } }区块模式:
typescript
{
type: 'object', list: true, name: 'blocks', label: '页面区块',
ui: { visualSelector: true },
templates: [heroBlock, featuresBlock, contentBlock, ctaBlock, faqBlock],
}每个区块模板需要:、、区块样式组(布局/背景/高度/文字颜色为枚举类型,映射到Tailwind类名)。
ui.previewSrcui.defaultItem字段质量规范——所有字段必须遵循:
- 标题字段添加,必填字段添加
isTitle: truerequired: true - 使用进行字符限制、格式验证
ui.validate - 添加提供编辑指导
ui.description - 所有列表字段添加,设置有意义的标签
ui.itemProps - 多行字符串使用,可折叠分组使用
ui.component: 'textarea''group'
可复用字段组——提取为共享变量:、、、、。
seoFieldsctaFieldslinkFieldsresponsiveImageFieldssectionStyleFields内容钩子:
typescript
ui: {
beforeSubmit: async ({ values }) => ({
...values,
slug: values.title.toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, ''),
modifiedDate: new Date().toISOString(),
}),
}Step 4: Server-Client Page Pattern
步骤4:服务端-客户端页面模式
See for the complete pattern.
templates/page-server-client.tsxtypescript
// app/[...slug]/page.tsx — Server Component
import client from '@/tina/__generated__/client'
import PageClient from './client-page'
export default async function Page({ params }: { params: Promise<{ slug: string[] }> }) {
const { slug } = await params
const relativePath = `${slug.join('/')}.md`
const { data, query, variables } = await client.queries.page({ relativePath })
return <PageClient data={data} query={query} variables={variables} />
}
export async function generateStaticParams() {
const pages = await client.queries.pageConnection()
return pages.data.pageConnection.edges?.map((edge) => ({
slug: edge?.node?._sys.breadcrumbs,
})) ?? []
}typescript
// app/[...slug]/client-page.tsx — Client Component
'use client'
import { useTina, tinaField } from 'tinacms/dist/react'
import { Blocks } from '@/components/blocks'
export default function PageClient(props: { data: any; query: string; variables: any }) {
const { data } = useTina(props)
return (
<main data-tina-field={tinaField(data.page, 'blocks')}>
<Blocks blocks={data.page.blocks} />
</main>
)
}完整示例请参考。
templates/page-server-client.tsxtypescript
// app/[...slug]/page.tsx — 服务端组件
import client from '@/tina/__generated__/client'
import PageClient from './client-page'
export default async function Page({ params }: { params: Promise<{ slug: string[] }> }) {
const { slug } = await params
const relativePath = `${slug.join('/')}.md`
const { data, query, variables } = await client.queries.page({ relativePath })
return <PageClient data={data} query={query} variables={variables} />
}
export async function generateStaticParams() {
const pages = await client.queries.pageConnection()
return pages.data.pageConnection.edges?.map((edge) => ({
slug: edge?.node?._sys.breadcrumbs,
})) ?? []
}typescript
// app/[...slug]/client-page.tsx — 客户端组件
'use client'
import { useTina, tinaField } from 'tinacms/dist/react'
import { Blocks } from '@/components/blocks'
export default function PageClient(props: { data: any; query: string; variables: any }) {
const { data } = useTina(props)
return (
<main data-tina-field={tinaField(data.page, 'blocks')}>
<Blocks blocks={data.page.blocks} />
</main>
)
}Step 5: Visual Editing & Draft Mode
步骤5:可视化编辑与草稿模式
Draft Mode API route ():
app/api/preview/route.tstypescript
import { draftMode } from 'next/headers'
import { redirect } from 'next/navigation'
export async function GET(request: Request) {
const { searchParams } = new URL(request.url)
const slug = searchParams.get('slug') || '/'
;(await draftMode()).enable()
redirect(slug)
}Visual editing debug checklist — if click-to-edit doesn't work:
- Draft mode enabled? ()
/api/preview - Component is ?
"use client" - called with correct
useTina()props?{ data, query, variables } - on DOM elements (not wrapper components)?
data-tina-field={tinaField(data.page, 'fieldName')} - Tina dev server running? ()
tinacms dev - Types generated and current? ()
tina/__generated__/
ui.routertypescript
ui: { router: ({ document }) => `/blog/${document._sys.filename}` }草稿模式API路由():
app/api/preview/route.tstypescript
import { draftMode } from 'next/headers'
import { redirect } from 'next/navigation'
export async function GET(request: Request) {
const { searchParams } = new URL(request.url)
const slug = searchParams.get('slug') || '/'
;(await draftMode()).enable()
redirect(slug)
}可视化编辑调试清单——若点击即编辑功能失效:
- 是否启用了草稿模式?(访问)
/api/preview - 组件是否添加了指令?
"use client" - 是否传入了正确的
useTina()参数?{ data, query, variables } - DOM元素上是否添加了(而非包装组件)?
data-tina-field={tinaField(data.page, 'fieldName')} - Tina开发服务器是否在运行?(执行)
tinacms dev - 类型文件是否已生成且为最新版本?(检查)
tina/__generated__/
**所有内容集合添加**以支持上下文编辑预览:
ui.routertypescript
ui: { router: ({ document }) => `/blog/${document._sys.filename}` }Step 6: Complete SEO Implementation
步骤6:完整SEO实现
Read — Day 1 tasks 1.16–1.98 for the exhaustive 80+ SEO field specs covering global settings singleton, per-page SEO object, article fields, JSON-LD schemas, OG tags, Twitter cards, discovery files.
references/day0-2-checklist.mdKey patterns:
SEO description waterfall:
- (explicit) → 2.
metaDescription→ 3. Auto-truncated content → 4.excerpt(global)siteDescription
generateMetadata()typescript
export async function generateMetadata({ params }: Props): Promise<Metadata> {
const { slug } = await params
const { data } = await client.queries.page({ relativePath: `${slug}.md` })
const seo = data.page.seo
const global = await client.queries.global({ relativePath: 'settings.json' })
return {
title: seo?.metaTitle || data.page.title,
description: resolveDescription(seo, data.page, global.data.global),
openGraph: {
images: resolveOgImage(seo, global.data.global),
type: 'website',
siteName: global.data.global.siteName,
},
robots: { index: !seo?.noIndex, follow: !seo?.noFollow },
alternates: { canonical: seo?.canonical || `${global.data.global.siteUrl}/${slug}` },
}
}JSON-LD — on every page: , (homepage), , / (posts), , (FAQ blocks).
OrganizationWebSiteWebPageArticleBlogPostingBreadcrumbListFAQPageDiscovery files:
- — dynamic from all collections, respects
app/sitemap.ts/noIndexdraft - — disallows
app/robots.ts,/admin/api/preview - — RSS for blog
app/feed.xml/route.ts
详细的80+项SEO字段规范请参考——第1天任务1.16–1.98,涵盖全局设置单例、页面级SEO对象、文章字段、JSON-LD Schema、OG标签、Twitter卡片、站点发现文件。
references/day0-2-checklist.md核心模式:
SEO描述优先级:
- (显式设置)→ 2.
metaDescription(摘要)→ 3. 自动截断的内容 → 4.excerpt(全局站点描述)siteDescription
每个页面添加:
generateMetadata()typescript
export async function generateMetadata({ params }: Props): Promise<Metadata> {
const { slug } = await params
const { data } = await client.queries.page({ relativePath: `${slug}.md` })
const seo = data.page.seo
const global = await client.queries.global({ relativePath: 'settings.json' })
return {
title: seo?.metaTitle || data.page.title,
description: resolveDescription(seo, data.page, global.data.global),
openGraph: {
images: resolveOgImage(seo, global.data.global),
type: 'website',
siteName: global.data.global.siteName,
},
robots: { index: !seo?.noIndex, follow: !seo?.noFollow },
alternates: { canonical: seo?.canonical || `${global.data.global.siteUrl}/${slug}` },
}
}JSON-LD Schema——每个页面添加:、(首页)、、/(文章)、、(FAQ区块)。
OrganizationWebSiteWebPageArticleBlogPostingBreadcrumbListFAQPage站点发现文件:
- — 从所有集合动态生成,尊重
app/sitemap.ts/noIndex状态draft - — 禁止爬虫访问
app/robots.ts、/admin/api/preview - — 博客RSS订阅源
app/feed.xml/route.ts
Step 7: Caching Strategy
步骤7:缓存策略
typescript
async function getPage(slug: string) {
'use cache'
cacheLife({ stale: 300, revalidate: 60, expire: 3600 })
const { data } = await client.queries.page({ relativePath: `${slug}.md` })
return data
}Draft mode bypasses all caches (confirmed after Next.js PR #77141). Next.js 15+ changed default to — explicitly opt into caching.
fetch()no-storetypescript
async function getPage(slug: string) {
'use cache'
cacheLife({ stale: 300, revalidate: 60, expire: 3600 })
const { data } = await client.queries.page({ relativePath: `${slug}.md` })
return data
}草稿模式会绕过所有缓存(Next.js PR #77141已确认)。Next.js 15+将默认改为——需显式启用缓存。
fetch()no-storeStep 8: Media Management
步骤8:媒体管理
| Provider | Best For | Setup |
|---|---|---|
Repo-based ( | Small sites, blogs | 2 lines in config |
Cloudinary ( | Media-heavy | Package + API route + 3 env vars |
S3/R2 ( | Enterprise | Package + IAM + bucket config |
All providers integrate with — add in .
next/imageimages.remotePatternsnext.config.js| 提供商 | 适用场景 | 配置方式 |
|---|---|---|
基于仓库( | 小型站点、博客 | 配置文件中添加2行代码 |
Cloudinary( | 媒体密集型站点 | 安装包 + API路由 + 3个环境变量 |
S3/R2( | 企业级站点 | 安装包 + IAM配置 + 存储桶设置 |
所有提供商均兼容——需在中添加配置。
next/imagenext.config.jsimages.remotePatternsStep 9: Build & Deploy
步骤9:构建与部署
json
{
"scripts": {
"dev": "tinacms dev -c \"next dev\"",
"build": "tinacms build && next build",
"start": "next start"
}
}Vercel env vars for Tina Cloud:
NEXT_PUBLIC_TINA_CLIENT_ID=<from app.tina.io>
TINA_TOKEN=<read-only token>
NEXT_PUBLIC_TINA_BRANCH=mainVercel env vars for self-hosted:
TINA_PUBLIC_IS_LOCAL=false
GITHUB_PERSONAL_ACCESS_TOKEN=ghp_xxx
NEXTAUTH_SECRET=<random-secret>
KV_REST_API_URL=https://xxx.kv.vercel-storage.com
KV_REST_API_TOKEN=xxxjson
{
"scripts": {
"dev": "tinacms dev -c \"next dev\"",
"build": "tinacms build && next build",
"start": "next start"
}
}Tina Cloud的Vercel环境变量:
NEXT_PUBLIC_TINA_CLIENT_ID=<来自app.tina.io>
TINA_TOKEN=<只读令牌>
NEXT_PUBLIC_TINA_BRANCH=main自托管的Vercel环境变量:
TINA_PUBLIC_IS_LOCAL=false
GITHUB_PERSONAL_ACCESS_TOKEN=ghp_xxx
NEXTAUTH_SECRET=<随机密钥>
KV_REST_API_URL=https://xxx.kv.vercel-storage.com
KV_REST_API_TOKEN=xxxWorkflow: Self-Hosted TinaCMS
工作流:自托管TinaCMS
Three pluggable components: database adapter (Vercel KV / MongoDB / custom), git provider (GitHub), auth provider (AuthJS/Clerk).
Read for configuration.
references/nextjs16-react19-tinacms-reference.md § Self-Hosted TinaCMSdatabase.tsChoose self-hosting for: full control, cost sensitivity, open-source purity.
Choose Tina Cloud for: quick setup, non-technical teams, built-in editorial workflow ($29-599/mo).
三个可插拔组件:数据库适配器(Vercel KV / MongoDB / 自定义)、Git提供商(GitHub)、认证提供商(AuthJS/Clerk)。
database.tsreferences/nextjs16-react19-tinacms-reference.md § 自托管TinaCMS选择自托管的场景:需要完全控制权、对成本敏感、追求开源纯粹性。
选择Tina Cloud的场景:快速搭建、面向非技术团队、内置编辑工作流(每月29-599美元)。
Common Gotchas
常见问题排查
| Problem | Cause | Fix |
|---|---|---|
| Wrong build order | |
| Frontend imports in | Keep imports minimal |
| Hyphens/spaces | Alphanumeric + underscores only |
| Missing | Add when using |
| Visual editing not working | Multiple causes | Run debug checklist (Step 5) |
| Turbopack prerendering bug | |
| List items show "Item 0" | Missing | Add meaningful label function |
| Reference dropdown slow/503 | Large collections | Custom field with pagination |
| SCSS modules broken | TinaCMS esbuild issue | CSS modules or Tailwind |
| Mismatched package versions | Tina packages out of sync | Pin exact, RenovateBot grouping |
| Content stale after Git push | Database index not updated | Re-index from dashboard |
| iOS share sheet broken (iMessage, AirDrop) | | Use |
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 构建顺序错误 | 执行 |
| | 最小化导入依赖 |
| 字段名称包含连字符/空格 | 仅使用字母数字+下划线 |
| Frontmatter中缺少 | 使用 |
| 可视化编辑功能失效 | 多种可能原因 | 执行步骤5中的调试清单 |
| Turbopack预渲染Bug | 使用 |
| 列表项显示"Item 0" | 缺少 | 添加有意义的标签函数 |
| 引用下拉框缓慢/503错误 | 集合数据量过大 | 使用带分页的自定义字段 |
| SCSS模块失效 | TinaCMS esbuild问题 | 使用CSS模块或Tailwind |
| 包版本不匹配 | Tina相关包版本不同步 | 固定精确版本,使用RenovateBot分组更新 |
| Git推送后内容未更新 | 数据库索引未更新 | 从后台重新索引 |
| iOS分享面板失效(iMessage、AirDrop) | | 使用 |
Anti-Patterns
反模式
| Don't | Do Instead |
|---|---|
| Single rich-text for page body | Blocks list with templates |
| Expose CSS values in schema | Enums mapped to Tailwind classes |
| Generic wrapper components | Purpose-built components accepting Tina types |
| Client Component wrapper |
| Dependabot for Tina packages | RenovateBot with grouping |
| Inline media (base64) | External media provider |
| No block fallback | Default case in renderer |
| Hardcoded SEO | SEO object in schema with waterfall |
Missing | Meaningful label functions |
Sync | |
Manifest | |
| 不推荐的做法 | 推荐替代方案 |
|---|---|
| 使用单个富文本字段作为页面主体 | 使用带模板的区块列表 |
| 在Schema中暴露CSS值 | 使用映射到Tailwind类名的枚举类型 |
| 使用通用包装组件 | 构建接收Tina类型的专用组件 |
在服务端组件中使用 | 使用客户端组件包装 |
| 使用Dependabot更新Tina包 | 使用带分组功能的RenovateBot |
| 使用内联媒体(base64) | 使用外部媒体提供商 |
| 区块未设置 fallback | 在渲染器中添加默认处理分支 |
| 硬编码SEO内容 | 在Schema中添加SEO对象并使用优先级策略 |
列表字段缺少 | 添加有意义的标签函数 |
同步访问 | 所有地方使用 |
非PWA站点设置 | 使用 |
Reference Files
参考文件
| File | Purpose |
|---|---|
| 247-task checklist — follow task-by-task for complete setup |
| Deep technical reference: schema patterns, field types, blocks, SEO, React 19, caching, self-hosting, custom components, deployment |
| Production |
| Complete server-client page pattern with metadata, static params, block renderer |
| 文件 | 用途 |
|---|---|
| 247项任务清单——完整搭建请逐项执行 |
| 深度技术参考:Schema模式、字段类型、区块、SEO、React 19、缓存、自托管、自定义组件、部署 |
| 生产级 |
| 完整的服务端-客户端页面模式,包含元数据、静态参数、区块渲染器 |