Typst Editor online

Code

Export

The PDF comes straight from the Typst compiler: the same pages as in the preview, with real text that can be selected and searched, links and the document's title.

My documents

Click a document to open it. They are stored only in this browser - nothing is uploaded. Clearing the browser's site data removes them, so download the ones you want to keep.

AI Assistant

Any AI can write with you - ChatGPT, Claude, Gemini, Copilot.

  1. Click Copy prompt.
  2. Paste it into your AI and say what it should write.
The AI should

The document travels in the link after the “#”, which no server sees. What you paste into your AI is handled by its provider.

Save to your server

The editor can send each saved version to your own server (a webhook), so your work is kept where you want it. Nothing is sent until you enter an address here.

What your server receives

A POST request with JSON (your server must allow CORS from https://typst.giit.ch):

{ "editor": "typst", "event": "save", "id": "…", "name": "Report",
  "content": "#set page(paper: \"a4\") …",
  "assets": { "logo.png": "data:image/png;base64,…" },
  "updated": "2026-01-15T09:30:00.000Z" }
Embed the editor in your website
<iframe src="https://typst.giit.ch/?embed=1" style="width:100%;height:80vh;border:0"></iframe>
<script>
const frame = document.querySelector('iframe');
addEventListener('message', e => {
  if (e.origin !== 'https://typst.giit.ch' || e.source !== frame.contentWindow) return;
  if (e.data.type === 'typsteditor:ready')
    frame.contentWindow.postMessage({ type: 'typsteditor:load', name: 'Report',
      content: '= Report\\n…', assets: {} }, 'https://typst.giit.ch');
  if (e.data.type === 'typsteditor:save') saveOnYourServer(e.data.content, e.data.assets);
});
</script>

Also possible: ?src=<URL of a .typ file> opens a file, &webhook=<URL> saves this document there. The editor can also open in a window of its own (?embed=window), and your page can hand it its own AI prompt and a session key so the AI sends its result to your server (typsteditor:ai, typsteditor:key-request) - see "Use the editor on your own website" below the editor. Details are in llms.txt.

Help

How it works

  1. Write Typst on the left - or start with New and one of the templates. The real Typst compiler runs in your browser and shows the pages as you type.
  2. Click text on the page to edit it right there: a field opens with the cursor where you clicked, and the code's cursor goes to the same place. Enter or a click elsewhere writes the change into the code (one step for Undo), Escape cancels. A click on math, a picture or text made by code jumps to its place in the code instead. The place where the code cursor is gets a frame on the page.
  3. Document on the right sets paper, font, margins and numbering (it edits the #set rules); Insert has ready-made pieces (lists, tables, math, symbols); Pictures holds the pictures and data files of the document; Outline lists the headings.
  4. The compiler's errors and warnings are listed above the code with line, column and hint - click one to go there.
  5. My documents (the folder button at the top left) lists every document kept in this browser.
  6. Export makes a PDF (from the Typst compiler, with real text) and pictures of the pages (PNG, JPG, WebP, SVG). Download .typ saves the code.

Packages from Typst Universe (#import "@preview/…") are not downloaded - nothing is loaded from other servers. Fonts: Libertinus Serif, New Computer Modern, DejaVu Sans Mono and the fonts you add to a document.

Keyboard shortcuts

Ctrl + B / I / U
Bold / italic / underline the selected text
Ctrl + M
Math: $…$ around the selection
Ctrl + /
Comment lines in or out (//)
Ctrl + Enter
Show the cursor's place on the pages
Tab / Shift + Tab
Indent / outdent
Ctrl + Z / Y
Undo / redo
Ctrl + S / E
Save (download .typ, or to your server) / export
Ctrl + O
My documents
Ctrl + P
Print the pages
Ctrl + mouse wheel, Ctrl + + -
Zoom the preview
Page Up / Page Down
Previous / next page (in the preview)

Enter in a list continues it (-, +, 1.); Enter on an empty item ends it. Brackets, $, * and _ go around a selection.

在线编写 Typst,使用真正的编译器

Typst 编辑器将你的代码和编译后的页面并排显示。它以 WebAssembly 形式在你的浏览器中运行真正的 Typst 编译器,因此页面与 PDF 中的效果完全一致,包括标题、列表、表格、公式、插图、脚注、引用以及你自己的 #set 和 #show 规则。点击页面上的任意文字,即可跳到它在代码中的位置,你也可以直接在页面上编辑文字。

一切都在你的浏览器中运行。文档不会上传,无需注册,也没有广告。

编辑器的功能

代码高亮

标记、代码、公式、字符串和注释各有颜色,带行号,按 Enter 自动续写列表,并显示编译器的错误及其行号、列号和提示。

真正的 Typst 编译器

编译为 WebAssembly 的 Typst 0.14 在编辑器旁的 Worker 中运行,每次更改后稍候即编译,输入依然流畅。

在页面上编辑

点击页面上的文字即可直接修改,更改会写入代码。点击公式或图片则会跳转到代码中的对应位置。

文档设置

纸张、页边距、分栏、字体、字号、语言、两端对齐、编号标题和页码:这些设置会编辑你代码中的 #set 规则。

图片和数据文件

为文档添加图片、CSV、JSON、YAML、参考文献、字体和其他 .typ 文件,并通过 image、csv、json 或 #import 使用它们。

导出

由编译器生成、文字真实可选的 PDF,每页导出为 PNG、JPG、WebP 或 SVG,或带文件的 .typ 源文件 ZIP。

使用方法

  1. 开始:在“新建”中选择模板,打开 .typ 文件或粘贴 Typst 代码。
  2. 编写:在代码中输入,右侧的页面随之更新。用“插入”添加表格、列表和公式。
  3. 导出:保存 PDF、页面图片或 .typ 文件。

在你自己的网站上使用编辑器

任何 https 页面(以及 localhost)都可以用 <iframe> 和 ?embed=1 嵌入编辑器,无需注册,无需密钥。嵌入后,编辑器会隐藏这段文字并显示“保存”按钮。有两种方式传入和取出文档。

1. 从链接打开文件,保存到你的服务器

src= 打开一个文件(你的服务器必须允许 CORS),webhook= 让“保存”(Ctrl+S)把文档发送到该地址。加上 &token=… 可发送 Authorization: Bearer … 请求头,加上 &auto 则每次更改后都会保存。

<iframe src="https://typst.giit.ch/?embed=1&src=https://your-site.com/docs/flyer.typ&webhook=https://your-site.com/save.php"
        allow="clipboard-write" style="width:100%;height:800px;border:0"></iframe>

Webhook 会收到一个带 JSON 的 POST 请求 { editor, event: "save", id, name, content, assets, updated }。一个保存它的简短 PHP 脚本:

<?php
header('Access-Control-Allow-Origin: https://typst.giit.ch');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
header('Access-Control-Allow-Methods: POST, OPTIONS');
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') exit;
if (($_SERVER['HTTP_AUTHORIZATION'] ?? '') !== 'Bearer SECRET') { http_response_code(403); exit; }
$d = json_decode(file_get_contents('php://input'), true);
$name = preg_replace('/[^\w\- ]/u', '_', $d['name']);
file_put_contents(__DIR__ . "/docs/$name.typ", $d['content']);
echo '{"ok":true}';

2. 由你的页面保存文档(postMessage)

编辑器发送 typsteditor:ready,你的页面以 typsteditor:load 回应,编辑器报告 typsteditor:loaded,有实际编辑时发送 typsteditor:change,用户保存时发送 typsteditor:save。你的页面可以发送 typsteditor:get(获取当前状态)或 typsteditor:save(相当于点击“保存”)。这样保存就通过你自己的登录和会话进行。

<iframe id="ed" src="https://typst.giit.ch/?embed=1" allow="clipboard-write" style="width:100%;height:800px;border:0"></iframe>
<script>
const ed = document.getElementById('ed');
const ORIGIN = 'https://typst.giit.ch';

addEventListener('message', async e => {
  if (e.source !== ed.contentWindow || e.origin !== ORIGIN) return;
  const m = e.data;
  if (m.type === 'typsteditor:ready') {             // 编辑器已就绪:把文档交给它
    ed.contentWindow.postMessage({
      type: 'typsteditor:load',
      name: 'Flyer',
      content: await (await fetch('/docs/flyer.typ')).text(),
      assets: { 'logo.png': 'data:image/png;base64,…' }   // 可选的图片和数据文件
    }, ORIGIN);
  }
  if (m.type === 'typsteditor:change') document.title = '● not saved';   // 一次实际编辑
  if (m.type === 'typsteditor:save') {              // 用户点击了“保存”
    await fetch('/api/save', { method: 'POST', headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ name: m.name, content: m.content, assets: m.assets }) });
    document.title = 'Saved';
  }
});

// 你自己页面上的保存按钮:回应以 typsteditor:save 返回
function saveNow() { ed.contentWindow.postMessage({ type: 'typsteditor:get' }, ORIGIN); }
</script>

页面内的 AI 助手:在框架中同样可用。在 iframe 上设置 allow="clipboard-write" 后,“复制提示词”会直接使用剪贴板(否则编辑器会退回旧的复制命令,或显示提示词供手动复制)。AI 发送的链接无法到达另一个网站中的编辑器,因此编辑器会提示 AI 和用户把 AI 的完整回答粘贴到编辑器中,或在单独的窗口中打开编辑器。

3. 在单独的窗口中

window.open("https://typst.giit.ch/?embed=window", "typsteditor-17") 会在单独的窗口中打开完整的编辑器,并通过 window.opener 使用相同的消息。AI 的链接可以到达那里。typsteditor:load 还可以带上 context: { host, title, rules }(AI 提示词随后会说明文档属于哪里,并遵循你的规则),以及 hook: { url, token, assets: false },即仅用于此文档、从不保存的 Webhook。关闭有未保存更改的窗口时会发送 typsteditor:closing。typsteditor:pdf 会请求页面文档的 PDF,并以 Data URI 形式返回,由 Typst 编译器生成,文字真实可选。

4. 通过你自己的服务器使用 AI

向编辑器提供你自己的提示词、你网站上的一个地址和本次编辑器会话的密钥。AI 对话框随后会显示“已连接到”你的网站、你告诉 AI 的内容,以及修改当前文档或新建一个文档的选项;复制提示词会把这些都组合起来。AI 带着密钥把结果发送到你的服务器,你的页面再在编辑器中打开它;新文档会单独打开,并保留在用户的浏览器中。每个编辑器会话一个密钥:编辑器打开期间有效,只有在没有密钥时,编辑器才会用 typsteditor:key-request 请求。编辑器自己从不发送密钥,也从不保存它;地址必须是你自己主机或其子域名上的 https 地址。

const key = async () => (await fetch('/api/ai-key.php?doc=17')).json();   // 每个编辑器会话一个密钥
const k = await key();
ed.contentWindow.postMessage({ type: 'typsteditor:load', name: 'Flyer', content, ai: {
  label: 'My Site', prompt: 'Keep the [[placeholders]]. Write in German.',
  endpoint: 'https://your-site.com/api/ai-result.php', key: k.key } }, ORIGIN);
// 记住 typsteditor:loaded 中的 id,忽略 id 不同的 change/save/closing
// 仅在编辑器没有密钥时:
if (m.type === 'typsteditor:key-request') { const k = await key(); ed.contentWindow.postMessage({ type: 'typsteditor:ai', key: k.key }, ORIGIN); }
// 编辑器打开期间,每分钟通知你的服务器;关闭编辑器或页面会使密钥作废
setInterval(() => fetch('/api/ai-key.php?alive=' + k.key.slice(0, 8)), 60000);
// 你的服务器有了结果(轮询、SSE …):target 为 "current" 或 "new"
ed.contentWindow.postMessage({ type: 'typsteditor:load', name: 'Flyer', content: draft, from: 'ai', target }, ORIGIN);
<?php // api/ai-key.php:已登录用户本次编辑器会话的密钥(由你的页面调用)
session_start();                                     // 检查用户是否可以编辑此文档
$key = bin2hex(random_bytes(24));
$_SESSION['ai'][hash('sha256', $key)] = ['doc' => (int)$_GET['doc'], 'seen' => time()];  // 或存入你的数据库;?alive= 会重新设置 seen
echo json_encode(['key' => $key]);

<?php // api/ai-result.php:AI 向这里发送(无需 CORS 头:AI 从服务器调用它)
$key = preg_replace('/^Bearer\s+/', '', $_SERVER['HTTP_AUTHORIZATION'] ?? '');
$row = find_key(hash('sha256', $key));               // 你的数据库:未作废,且在最近 3 分钟内出现过
if (!$row) { http_response_code(401); exit('{"ok":false,"error":"key not valid"}'); }
$d = json_decode(file_get_contents('php://input', false, null, 0, 2000000), true);
save_draft($row['doc'], $d['content'], $d['target'] === 'new' ? 'new' : 'current');   // 你的页面用 typsteditor:load 显示它
echo '{"ok":true}';

密钥至少使用 128 位随机数,只保存其哈希值,将每个密钥绑定到已登录用户、文档和本次编辑器会话,每个会话一个,仅在你的页面报告会话仍打开时有效,并在编辑器或页面关闭时作废。

完整协议见 llms.txt,把它交给 AI,AI 就能为你的系统建立连接。LaTeX 编辑器的用法相同,前缀为 latexeditor:,见 latex.giit.ch。

常见问题

我的文档会被上传吗?

不会。编辑器和 Typst 编译器完全在你的浏览器中运行。你的文档、图片和文件绝不会发送到服务器,除非你自己设置了指向自己服务器的 Webhook。

这是真正的 Typst 编译器吗?

是的。编辑器运行编译为 WebAssembly 的 Typst 0.14(typst.ts),因此页面和 PDF 与 Typst 命令行的结果相同。它只加载一次(约 11 MB),之后由你的浏览器缓存。

如何得到 PDF?

点击“导出”,选择 PDF,再点击“下载”。PDF 直接由 Typst 编译器生成,文字真实,可以选中和搜索。

可以使用 Typst Universe 中的包吗?

不能直接使用:编辑器不会从其他服务器加载任何内容,因此 #import "@preview/…" 会报告一个指明该包的问题。你可以在“图片”标签页中把包的 .typ 文件添加到文档,并按文件名导入。

有哪些字体?

Typst 自带的字体:Libertinus Serif(默认)、New Computer Modern 及其数学字体,以及用于代码的 DejaVu Sans Mono。你可以向文档添加自己的 .otf 或 .ttf 文件,并通过 #set text(font: "Name") 使用。

如何添加图片?

将图片拖入或粘贴到编辑器中,或在右侧的“图片”标签页中添加。图片与文档一起保存在你的浏览器中,通过 #image("name.png") 使用。CSV、JSON、YAML 和 .bib 文件的用法相同。

AI 能在 Typst 编辑器中写作吗?

能,任何 AI 都可以:ChatGPT、Claude、Gemini、Copilot 或你编程工具中的 AI。点击“AI 助手”,再点击“复制提示词”,粘贴到你的 AI 中并说明要写什么。AI 会回复一个链接;点击它,文档就会出现在你的编辑器中。“撤销”可撤回每一处更改。

我可以在自己的网站上使用编辑器吗?

可以。用 iframe 嵌入它并通过 postMessage 交换文档,或让它通过 Webhook 把每个保存的版本发送到你的服务器。示例见在你自己的网站上使用编辑器。

Typst 编辑器收费吗?

不收费。编辑器免费,没有广告,无需注册。