在 Next.js 中集成 tldraw SDK:基于官方模板从零搭建无限画布应用
导读
本指南以官方 Next.js 模板 为核心,讲解如何把 tldraw SDK 集成进 Next.js 应用,从安装依赖、启动开发服务器,到理解 Tldraw 组件的挂载方式与相关配置文件的底层作用。读完本文,你将能够基于 App Router 架构快速搭建一个全屏可用的画布应用,并掌握在生产构建、TypeScript 与样式加载等环节中需要注意的关键配置。
模板定位:一个最小可运行的 tldraw + Next.js 起点
仓库根目录下的 templates/ 目录维护了多套官方脚手架,nextjs 模板正是其中为 Next.js 框架量身定制的一套:它把 tldraw SDK 与 Next.js 的 App Router 目录结构整合在一起,开箱即用。模板的真实文件结构如下:
templates/nextjs/
├── LICENSE.md # 模板自身的 MIT 许可
├── README.md # 使用说明(本指南依据的文档)
├── next.config.mjs # Next.js 配置
├── package.json # 依赖与脚本
├── tsconfig.json # TypeScript 配置
└── src/
└── app/
├── favicon.ico
├── globals.css # 全局样式,引入 tldraw 的样式文件
├── layout.tsx # 根布局,输出页面 metadata
└── page.tsx # 首页,挂载 <Tldraw /> 组件
模板的核心目标是展示“在 Next.js 中使用 tldraw 的最小正确姿势”:一个 page.tsx、一个根布局、一个全局样式文件,外加三条 npm scripts。所有其他能力(持久化、多人协作、自定义 UI)都建立在这套骨架之上。
本地开发:三步跑起来
README 明确给出了本地开发的完整流程,这是从零开始的第一步,共三步:
- 安装依赖:使用
yarn或npm install(项目包管理器可二选一,package.json 中声明了全部依赖)。 - 启动开发服务器:运行
yarn dev或npm run dev。 - 打开浏览器:访问
http://localhost:3000/即可看到全屏画布应用。
在 monorepo 场景下,开发者通常从仓库根目录执行 yarn dev(配合 lerna.json 与根 package.json 的工作区机制),模板内的脚本定义如下:
"scripts": {
"dev": "next dev -H 0.0.0.0",
"build": "next build",
"start": "next start",
"lint": "yarn run -T tsx ../../internal/scripts/lint.ts"
}
几个值得注意的细节:
dev脚本带有-H 0.0.0.0,允许通过局域网 IP 访问开发服务器,便于在容器或远程环境中调试;lint复用了仓库根目录internal/scripts/lint.ts的统一 lint 流程,而不是在模板内单独配置 lint;build/start分别是生产构建与生产启动命令,与next dev形成完整闭环。
核心代码拆解:画布是如何挂载的
1. 页面组件:三行代码渲染画布
模板的首页位于 page.tsx,全文如下:
'use client'
import { Tldraw } from 'tldraw'
export default function Home() {
return (
<main>
<div style={{ position: 'fixed', inset: 0 }}>
<Tldraw />
</div>
</main>
)
}
这里有两个关键点:
'use client'指令:由于Tldraw组件依赖浏览器 API(如 Pointer Events、IndexedDB 等),在 Next.js App Router 中必须显式声明为客户端组件,否则服务端渲染阶段会报错。这是模板中最重要的集成要点。position: fixed; inset: 0:将外层容器固定并撑满整个视口,使画布获得全屏的交互区域。Tldraw组件会创建自己的编辑器实例与无限画布坐标系,无需任何其他 props 即可获得完整功能(选择、绘制、标注、导出等)。
2. 根布局:注入全局样式与 metadata
layout.tsx 定义了根布局,导入全局样式并输出页面元信息:
import './globals.css'
export const metadata = {
title: 'tldraw Next.js app template',
description: 'An example of how to use tldraw in a Next.js app',
}
值得注意的是,模板没有引入任何 UI 库或字体渲染框架,metadata 也保持极简,把渲染空间完全交给 tldraw。
3. 全局样式:必须引入 tldraw.css
globals.css 是让画布“看起来正常”的关键:
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@500;700&display=swap');
@import url('tldraw/tldraw.css');
body {
font-family: 'Inter';
overscroll-behavior: none;
}
@import url('tldraw/tldraw.css')通过包名直接引入 tldraw 打包产出的样式文件。该文件由 packages/tldraw 的构建脚本(scripts/copy-css-files.mjs)拷贝生成,并被列入包的files字段随 npm 包一起发布;overscroll-behavior: none禁用浏览器在画布边缘的滚动链式回弹,避免拖动画布时触发整页滚动——这是所有嵌入类画布应用的通用最佳实践;- 模板选用 Inter 字体,并声明了
500/700两个字重以满足工具面板的文字渲染需求。
4. Next.js 配置:将 tldraw 标记为服务端外部包
next.config.mjs 中有一项容易被忽视但至关重要的配置:
/** @type {import('next').NextConfig} */
const nextConfig = {
serverExternalPackages: ['@tldraw/tldraw'],
}
export default nextConfig
serverExternalPackages 告诉 Next.js 不要把 @tldraw/tldraw 打进服务端 bundle,而是作为外部包在运行时解析。tldraw 内部依赖浏览器全局对象与第三方库(如 idb、lz-string、@tiptap/*),此配置可以有效规避服务端打包时的兼容性问题,确保 'use client' 组件在客户端正确加载。
5. TypeScript 配置:路径别名与项目引用
tsconfig.json 采用 Next.js 标准配置,其中有两点与 tldraw 相关:
paths定义@/*指向./src/*,方便业务代码使用短路径导入;references指向../../packages/tldraw,让模板在 monorepo 中直接引用 tldraw 源码包(package.json中"tldraw": "workspace:*"与之对应),这是模板能够跟随 SDK 主分支实时迭代的前提。
底层原理:Tldraw 组件从何而来
模板只引入了 Tldraw 这一个组件,但它背后是完整的 SDK 导出体系。packages/tldraw/src/index.ts 中的导出语句说明了组件来源:
export { Tldraw, type TLComponents, type TldrawBaseProps, type TldrawProps } from './lib/Tldraw'
该文件同时通过 export * from '@tldraw/editor'(index.ts)透传了编辑器层能力,并从 packages/editor(含 @tldraw/state、@tldraw/store、@tldraw/tlschema 等核心包)逐层构建出完整 SDK。从依赖声明看,packages/tldraw/package.json 的 peerDependencies 要求 react / react-dom 版本为 ^18.2.0 || ^19.2.1,而模板固定使用 React 19 与 Next.js 16,版本组合是官方验证过的。
需要特别说明:<Tldraw /> 不带任何 props 时提供的是完整的编辑器 + 默认 UI(工具栏、样式面板、菜单等)。SDK 还导出 TldrawImage(index.ts)等组件以及大量可替换的 UI 部件(DefaultToolbar、DefaultMainMenu 等),模板的“零配置可用”正是这套默认装配的体现。
生产构建与部署
完成 yarn dev 本地验证后,生产环境流程为:
yarn build # 产出 .next 静态构建产物
yarn start # 以生产模式启动服务
由于画布状态默认保存在浏览器本地(tldraw 自带基于 IndexedDB 的持久化),该模板无需后端即可作为一个完整的单机白板应用部署到任意支持 Node.js 的平台。如果需要多人实时协作或云端存储,可以在此基础上接入仓库中的 sync、sync-core 等协作包,或参考 apps/dotcom 的生产级实现。
许可与使用边界
模板自身采用 MIT 许可(见 templates/nextjs/LICENSE.md),而 tldraw SDK 采用其独立的商业许可,二者是分离的:MIT 许可只覆盖模板脚手架代码,不覆盖 SDK 本体。仓库根目录的 LICENSE.md 与 TRADEMARKS.md 分别说明了 SDK 的许可条款与 tldraw 名称、Logo 的商标使用规范,商用前务必阅读确认。
小结
官方 Next.js 模板用最精简的文件证明了 tldraw 与 Next.js 的集成路径:一个 'use client' 页面挂载 <Tldraw />、一份引入 tldraw/tldraw.css 的全局样式、一条 serverExternalPackages 配置,再加上 dev/build/start 三条脚本,即可完成从本地开发到生产部署的完整闭环。以这套骨架为起点,你可以继续借助 packages/tldraw/src/index.ts 中导出的编辑器 API 与 UI 覆盖机制,逐步定制属于自己的无限画布应用。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust4.2 K634
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown300
jforgamejforgame是一个一站式游戏服务器开发框架。包含游戏服务器开发所需要的各种组件,比如网关,socket服务端与客户端,自定义高效消息编解码,游戏热更新,游戏通用工具等等。包含游戏服,跨服,匹配服,后台管理系统等实现,同时提供大量业务案例以供学习。亦可用于其他socket应用,例如及时聊天等。Java101
fizz-gateway-nodeAn Aggregation API Gateway in Java . FizzGate 是一个基于 Java开发的微服务聚合网关,是拥有自主知识产权的应用网关国产化替代方案,能够实现热服务编排聚合、自动授权选择、线上服务脚本编码、在线测试、高性能路由、API审核管理、回调管理等目的,拥有强大的自定义插件系统可以自行扩展,并且提供友好的图形化配置界面,能够快速帮助企业进行API服务治理、减少中间层胶水代码以及降低编码投入、提高 API 服务的稳定性和安全性。Java60
certd开源SSL证书管理工具;全自动证书申请、更新、续期;通配符证书,泛域名证书申请;证书自动化部署到阿里云、腾讯云、主机、群晖、宝塔;https证书,pfx证书,der证书,TLS证书,nginx证书自动续签自动部署JavaScript60
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python280