
从本地到云端TinaCMS 自托管 Starter 的 Next.js 内容编辑完整实战指南【免费下载链接】tinacmsTinaCMS is the leading open-source headless CMS that supports Markdown and Visual Editing. Your content is stored in your own GitHub repo ❤️项目地址: https://gitcode.com/GitHub_Trending/ti/tinacms本文以 examples/next/tina-self-hosted-demo 中的启动指南为骨架展开带你从零走通一条完整链路用本地文件系统驱动 GraphQL API 编辑 Markdown 内容接入 TinaCloud 云端认证与内容 API再部署到 Vercel / Netlify 让团队协作编辑。读完你会掌握 TinaCMS 文件型 CMS 的本地开发工作流、Schema 驱动自动生成表单的原理、环境变量切换本地/云端客户端的机制以及把内容写回 GitHub 仓库的完整配置方法。这个 Starter 是什么文件即内容Schema 即表单TinaCMS 的核心哲学是内容以 Markdown 文件形式存放在你自己的 Git 仓库中而非存储在第三方数据库里。examples/next/tina-self-hosted-demo是官方为此提供的自托管self-hosted演示项目一个基于 Next.js 的博客/落地页站点它的页面、文章、作者、全局配置全部以content/目录下的文件形式存在content/pages/页面内容Markdown如home.md、about.mdcontent/posts/博客文章MDXcontent/authors/作者信息Markdowncontent/global/index.json站点全局配置JSON正如文档中所强调的在这个项目中Tina 文件型 CMS 是通过 GraphQL 使用的它由一份由你定义的 Schema驱动。Schema 不仅决定了从仓库 Markdown 文件提供内容的方式还会自动为你生成 TinaCMS 的表单——这就是编辑体验的来源你在侧边栏看到的每一个字段都直接对应 Schema 中定义的字段而保存即写回本地文件或 GitHub。从 tina/config.tsx 可以看到该演示站点的 Schema 结构post博客文章MDX、global全局配置JSON、author作者Markdown、page页面Markdown四个集合。每个集合用path指定内容存放目录、用format指定文件格式md/mdx/json、用fields描述可编辑字段。例如page集合定义了一个blocks字段包含hero、features、content、testimonial四种模板配合ui.visualSelector实现可视化区块选择——这正是本站about.md中 Frontmatter 里_template: content、color: default等元数据的来源。本项目能做什么文档明确了四个目标范围这也是你评估该 Starter 是否适合你的依据使用仓库内的本地内容在本地运行项目连接 TinaCloud使用其 GraphQL 内容 API部署站点后在线可视化编辑邀请协作者共同编辑内容。环境要求在动手之前请确认你的机器满足以下条件Git用于 fork 与 clone 仓库Node.js Active LTS即 Node.js 当前维护中的 LTS 版本可参考 nodejs.org 的发布节奏Yarn本项目以 Yarn 为包管理器。第一步Fork 并安装依赖Fork 仓库文档特别强调首先要 fork 仓库再克隆到本地。原因在于后续要连接 TinaCloud、并把编辑结果写回你的 GitHub 仓库——只有在你自己的 fork 上内容变更才能直接推送到你的仓库。安装依赖本项目使用yarn作为包管理器。如果机器上尚未安装 Yarn可以先通过 npm 全局安装npm install -g yarn然后安装项目依赖yarn install⚠️ 如果你更习惯使用npm请注意仓库中没有package-lock.json因此无法保证 npm 安装出的依赖版本与 Yarn 完全一致。官方文档建议使用 Yarn。从 package.json 可以看到本项目的核心依赖它们共同构成了自托管编辑链路tinacmsTinaCMS 核心提供defineStaticConfig、LocalAuthProvider与 React 侧编辑上下文tinacms/cli提供tinacms dev、tinacms build等 CLI 命令负责本地 GraphQL 服务器、Schema 类型生成与静态管理后台构建tinacms/datalayer数据层抽象本地用createLocalDatabase云端用createDatabase连接 MongoDB 与 GitHub Providertinacms-authjs、tinacms-gitprovider-github分别提供基于 Auth.js 的用户名密码认证与 GitHub 内容读写。第二步本地运行与本地编辑启动开发服务器yarn dev这个命令做三件事对应 package.json 中dev: cross-env TINA_PUBLIC_IS_LOCALtrue tinacms dev -c \next dev\启动GraphQL 服务器默认http://localhost:4001以开发模式启动Next.js 应用默认http://localhost:3000重新生成 Schema 类型TypeScript 与 GraphQL 的.tina相关类型使你对.tina配置的改动立即反映到类型与 API 中。关于本地开发文档特别强调了一个关键认知TinaCloud 内容 API 在本地运行并不依赖云端。因为 Tina 默认是 Git 后端 CMS一切都可以通过 CLI 在本地文件系统上完成。这意味着本地开发时使用的 GraphQL API 与云端 API完全一致一旦你准备好部署不会遇到 API 兼容性问题本地开发工作流因此成为官方推荐的开发方式。启动后在浏览器打开http://localhost:3000就能看到从 GraphQL API 加载出来的文件型内容。调试提示Tina 的 GraphQL GUI 位于http://localhost:4001/altair你可以在这里直观地看到 Schema 修改如何实时反映到 GraphQL 查询与类型上。配置本地编辑所需的变量要在本地进入编辑模式需要先把.env.example复制为.envcp .env.example .env其中只需关注一个变量NEXT_PUBLIC_USE_LOCAL_CLIENT设为1其余值暂时可以忽略。从 tina/config.tsx 与 tina/database.ts 的源码可以印证这个变量的作用二者都通过process.env.TINA_PUBLIC_IS_LOCAL true由dev脚本注入判断本地环境——本地时使用LocalAuthProvider与createLocalDatabase()非本地时使用UsernamePasswordAuthJSProvider与连接 MongoDB GitHub 的createDatabase()。也就是说本地/云端的行为切换是编译期由环境变量决定的。进入编辑模式并修改内容重启服务器后访问http://localhost:3000/点击右上角的enter edit mode按钮。此时页面看起来一样但左下角会出现一个铅笔图标点击铅笔图标打开 Tina 的侧边栏里面展示了一个由 Schema 自动生成的表单修改任意字段页面会实时更新visual editing由于当前是本地模式点击保存会将变更写入本地文件系统。文档还给出了进入编辑模式的第二种途径与一个开关NOTE本项目有两种进入编辑模式的方式点击 enter edit mode 按钮或直接访问/admin。你也可以通过设置NEXT_PUBLIC_SHOW_EDIT_BTN0来禁用页面上的编辑按钮。结合 next.config.js 可以看到/admin路径通过 rewrite 指向/admin/index.html——这是tinacms build时生成的静态管理后台入口只有在编辑模式下 Tina 才会被加载因此不会影响生产环境的 bundle 体积。本地流程走通之后你就已经具备构建自己项目的能力了。文档建议在动手改造前先阅读下文Starter 结构解析一节了解项目是如何组织的、如何改成你自己的项目。第三步连接 TinaCloud本地开发流程适合开发者自己使用但你显然希望其他编辑与协作者能在托管网站上通过认证进行修改。ℹ️ 注意编辑模式下的修改会在站点完成一次 rebuild 之后才出现在你的主页上TinaCloud 的变更同步到 Git 触发构建。在 TinaCloud 注册本地应用访问 app.tina.io 注册页面创建组织并登录记下你的组织名称Organization Name创建一个连接到你刚刚 fork 的 GitHub 仓库的 TinaCloud App创建完成后进入 App 设置复制 Client ID。配置本地项目连接 TinaCloud在env.local中设置以下变量变量值作用NEXT_PUBLIC_USE_LOCAL_CLIENT0关闭本地客户端走云端NEXT_PUBLIC_ORGANIZATION_NAME你的 TinaCloud 组织名标识组织NEXT_PUBLIC_TINA_CLIENT_IDTinaCloud App 的 Client ID标识应用NEXT_PUBLIC_SHOW_EDIT_BTN0或10表示页面上不显示 enter edit mode 按钮需通过/admin进入编辑模式设置完成后重启服务器并再次运行yarn dev。打开http://localhost:3000/点击 enter edit mode这次会出现一个认证弹窗要求通过 TinaCloud 登录。认证成功后你的编辑会被发送到云端服务器再由云端同步到 GitHub。编辑并保存到 GitHub通过侧边栏做一些编辑并点击保存变更会被写入你的 GitHub 仓库。确认 TinaCloud 编辑链路正常后就可以部署站点让团队成员也参与编辑了。⚠️ 一个容易踩的坑由于变更被直接同步到 GitHub当你在非编辑模式下浏览页面时看到的仍是本地文件系统中未经编辑的数据。这在本地调试时大多无碍TinaCloud 编辑本是为托管环境设计的但要注意Schema 的变更可能导致 TinaCloud API 与本地客户端之间出现不匹配请留意 Schema 的一致性。第四步部署到生产环境部署到 Vercel点击文档中的 Deploy with Vercel 按钮连接到你的 GitHub 仓库并设置与env.local相同的环境变量NEXT_PUBLIC_ORGANIZATION_NAME YOUR_ORGANIZATION NEXT_PUBLIC_TINA_CLIENT_ID YOUR_CLIENT_ID部署完成后站点即上线。验证方式访问[你的部署URL]/点击 edit this site登录 TinaCloud 并做几处修改确认变更被保存到 GitHub 仓库。结合 tina/config.tsx 源码可见部署平台相关的分支变量已内置支持NEXT_PUBLIC_TINA_BRANCH可自定义分支覆盖否则回退到 Vercel 的NEXT_PUBLIC_VERCEL_GIT_COMMIT_REF或 Netlify 的HEAD环境变量。这些变量最终用于确定 Tina 所操作的分支。部署到 Netlify点击文档中的 Deploy to Netlify 按钮连接到 GitHub 仓库后将build command设置为yarn build将publish directory设置为.next/。然后点击Advanced添加与env.local相同的环境变量NEXT_PUBLIC_ORGANIZATION_NAME YOUR_ORGANIZATION NEXT_PUBLIC_TINA_CLIENT_ID YOUR_CLIENT_ID粘贴你的 Organization ID 与 Client ID点击 Deploy site。完成后建议安装Next on Netlify 插件以启用 Next.js 的服务端渲染与预览特性最后触发一次新的部署让变更生效。同样地通过[你的部署URL]/→ edit this site → 登录 TinaCloud → 编辑 → 确认变更保存到 GitHub 仓库即可验证部署配置正确。部署相关的构建命令在 package.json 中可以看到完整形态build: tinacms build next build、start: tinacms build next start、export: npm run build next export。其中tinacms build会构建位于public/admin的静态后台对应 config 中build.outputFolder: admin这正是/admin路由得以工作的前提。Starter 结构解析从 Schema 到页面的数据流TinaCloud Starter 是一个 Next.js 应用文件路由由pages目录承担。要编辑本站点访问/admin路由即可进入编辑模式并加载 TinaTina 仅在编辑模式下加载因此不会影响生产 bundle 体积。tina/config.tsxSchema 即 API 形态这是整个项目的合同文件。修改这里生成的 GraphQL API 也会同步变化。文档建议在编辑 Schema 时保持 GraphQL 服务器运行以便即时发现破坏性变更——这也是把http://localhost:4001/altair当作 Schema 调试台的原因。具体到 tina/config.tsx还有几处值得注意的配置contentApiUrlOverride: /api/tina/gql把内容 API 请求路由到 Next.js 自己的 API 路由配合 pages/api/tina/[...routes].ts 中的TinaNodeBackend使用media.tina配置 TinaCloud 媒体存储publicFolder: public、mediaRoot: uploads表示上传文件落在public/uploadsauthProvider本地用LocalAuthProvider云端用UsernamePasswordAuthJSProvider配合tinacms-authjs与TinaUserCollection用户集合实现用户名密码认证schema.collections定义post/global/author/page四个集合包括字段类型string、image、rich-text、reference、datetime、object等以及ui.router回调把编辑中的文档路由映射到前台页面如home.md → /、about.md → /about。pages/[filename].tsx页面数据加载该页面在http://localhost:3000/可见结合 next.config.js 的 rewrite/→/home它从content/pages/home.md加载内容。源码 pages/[filename].tsx 展示了标准模式getStaticProps通过生成的databaseClient.queries.contentQuery({ relativePath: \${params.filename}.md }) 从本地 GraphQL 服务器取数getStaticPaths遍历pageConnection得到所有页面的_sys.filename动态生成静态路径组件内部用useTina({ query, variables, data })包裹数据使编辑时数据能够被实时水合hydrate并热更新。pages/posts/[filename].tsx博客文章路由文章存放在content/posts目录路由通过getStaticPaths在构建期动态生成。其实现位于 pages/posts/[filename].tsxgetStaticProps调用blogPostQuery({ relativePath: \${params.filename}.mdx })getStaticPaths遍历postConnection把每个 post 的 filename 作为 URL 路径段——例如content/posts/hello.md会生成http://localhost:3000/posts/hellofallback: blocking允许尚未预构建的新文章按需生成。查询定义见 tina/queries/queries.gqlcontentQuery、blogPostQuery、pageQuery等查询通过databaseClient位于tina/__generated__/由 CLI 生成执行。文档同时指出getStaticPropsForTina、staticRequest这类辅助函数的作用是确保从本地 GraphQL 服务器返回的数据是 Tina 认识的形状如果你愿意完全可以换上自己的 HTTP 客户端。content目录内容存放处这里存放真实内容。内容如何存储由defineSchema中的format决定——默认是markdown本项目中post使用mdx、global使用json。components目录演示用组件项目中的组件大多非常简单仅用于演示目的。组件与 Schema 的对应关系可以在 components/blocks-renderer.tsx 中看到它根据区块的__typename如PageBlocksContent、PageBlocksHero将数据分发到Content、Hero、Features、Testimonial组件并为每个区块设置data-tinafield属性——这正是可视化编辑时点击即定位字段的机制。例如 components/blocks/content.tsx 中contentBlockSchema定义了bodyrich-text与color枚举字段而组件用TinaMarkdown渲染富文本。你可以放心地替换成自己的组件。pages/_app.tsx全局包裹逻辑_app.tsx是 Next.js 的特性允许你为所有路由包裹统一逻辑。本项目用它把站点内容包裹进 TinaCMS 上下文使数据在传递时被**实时水合hydrate**以便在线编辑。其实现位于 pages/_app.tsx。值得注意当前版本通过isClient状态处理水合hydration问题——客户端挂载前不渲染组件从而规避编辑模式下前后端渲染不一致的问题。结合文档说明你可以体会到其设计意图在编辑模式下才动态加载 TinaCMS 及其全部能力非编辑模式下 Tina 完全不参与构建保持轻量。另外文档提到项目默认把showEditButton设为true。如果你不希望站点访客看到编辑按钮建议移除该选项或在.env中设置NEXT_PUBLIC_SHOW_EDIT_BTN0如前文所述。创建你自己的页面文档给出了 TinaCMS 当前推荐的三步模式数据获取使用getStaticProps从getStaticProps返回携带data、query、variables三个属性的数据在_app.tsx中动态包裹 TinaCMS。完成这三步之后就可以自由构建自己的页面了。浏览文档、查询 GraphQL API 的方式也很简单在你的 Tina 项目中运行yarn dev然后访问http://localhost:4001/altair。关键文件速查文件作用tina/config.tsx定义集合 Schema、认证方式、媒体与构建配置驱动 GraphQL API 与表单生成tina/database.ts本地使用createLocalDatabase()云端使用 MongoDB GitHub Provider 的createDatabase()tina/queries/queries.gql页面、文章、布局所需的 GraphQL 查询片段pages/api/tina/[...routes].ts自托管模式下处理内容 API 请求的 Next.js 路由按本地/云端切换后端认证pages/[filename].tsx首页/普通页面的静态数据加载与编辑水合pages/posts/[filename].tsx博客文章的静态路径生成与数据加载pages/_app.tsx全局水合处理components/blocks-renderer.tsx按__typename分发渲染页面区块next.config.js/→/home与/admin→/admin/index.html的 rewritepackage.jsondev/build/start脚本与全部依赖故障排查与帮助渠道TinaCloud 当前处于 public alpha 阶段遇到问题时可参考阅读 TinaCloud 官方文档加入官方 Discord 社区提问访问社区论坛community forum提问在 Twitter 上联系tina_cms发送邮件预约团队沟通说明你的使用场景与目标使用 TinaCloud Dashboard 上的聊天组件获取支持。结语从本地文件系统到 TinaCloud 云端、再到 Vercel / Netlify 生产部署这个自托管 Starter 完整展示了 TinaCMS 内容属于你自己的仓库的核心设计。理解tina/config.tsx中 Schema 与表单、GraphQL API 的联动关系掌握NEXT_PUBLIC_USE_LOCAL_CLIENT等环境变量对本地/云端行为切换的影响你就拥有了把任何 Next.js 站点改造成可视化编辑 CMS 的完整工具箱。下一站在哪里打开 tina/config.tsx把你的 Schema 改成自己的业务模型然后去http://localhost:4001/altair看看 API 的变化吧。【免费下载链接】tinacmsTinaCMS is the leading open-source headless CMS that supports Markdown and Visual Editing. Your content is stored in your own GitHub repo ❤️项目地址: https://gitcode.com/GitHub_Trending/ti/tinacms创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考