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.

Pisz w Typst online z prawdziwym kompilatorem

Edytor Typst pokazuje kod i skompilowane strony obok siebie. Uruchamia w przeglądarce prawdziwy kompilator Typst jako WebAssembly, więc strony wyglądają dokładnie tak jak w PDF - nagłówki, listy, tabele, wzory, rysunki, przypisy, odsyłacze oraz twoje własne reguły #set i #show. Kliknięcie dowolnego tekstu na stronie przenosi do jego miejsca w kodzie, a tekst można edytować bezpośrednio na stronie.

Wszystko działa w przeglądarce. Dokumenty nie są nigdzie wysyłane, nie ma rejestracji ani reklam.

Co potrafi edytor

Kod z podświetlaniem

Znaczniki, kod, wzory, łańcuchy znaków i komentarze we własnych kolorach, numery wierszy, listy kontynuowane po naciśnięciu Enter oraz błędy kompilatora z wierszem, kolumną i wskazówką.

Prawdziwy kompilator Typst

Typst 0.14 skompilowany do WebAssembly działa w wątku roboczym obok edytora i kompiluje chwilę po każdej zmianie - pisanie pozostaje płynne.

Edycja na stronie

Kliknij tekst na stronie, aby go tam zmienić; zmiana trafia do kodu. Kliknięcie wzoru lub obrazu przenosi do jego miejsca w kodzie.

Ustawienia dokumentu

Papier, marginesy, kolumny, czcionka, rozmiar, język, wyjustowany tekst, numerowane nagłówki i numery stron - ustawienia zmieniają reguły #set w twoim kodzie.

Obrazy i pliki danych

Dodawaj do dokumentu obrazy, pliki CSV, JSON, YAML, bibliografie, czcionki i inne pliki .typ i używaj ich przez image, csv, json lub #import.

Eksport

PDF z kompilatora z prawdziwym tekstem do zaznaczania, każda strona jako PNG, JPG, WebP lub SVG albo źródło .typ z plikami jako ZIP.

Jak to działa

  1. Start - wybierz szablon w menu „Nowy”, otwórz plik .typ lub wklej kod Typst.
  2. Pisanie - wpisuj kod; strony po prawej nadążają za nim. Tabele, listy i wzory znajdziesz w „Wstaw”.
  3. Eksport - zapisz PDF, obrazy stron lub plik .typ.

Edytor na własnej stronie

Każda strona https (i localhost) może osadzić edytor za pomocą <iframe> i ?embed=1 - bez rejestracji, bez klucza. Po osadzeniu edytor ukrywa ten tekst i pokazuje przycisk Zapisz. Dokument można przekazywać do edytora i z niego na dwa sposoby.

1. Otwieranie pliku z linku, zapis na twoim serwerze

src= otwiera plik (twój serwer musi zezwalać na CORS), webhook= sprawia, że „Zapisz” (Ctrl+S) wysyła dokument pod ten adres. Dodaj &token=…, aby wysyłać nagłówek Authorization: Bearer …, i &auto, aby zapisywać po każdej zmianie.

<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 otrzymuje żądanie POST z JSON { editor, event: "save", id, name, content, assets, updated }. Mały skrypt PHP, który go zapisuje:

<?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. Dokument przechowuje twoja strona (postMessage)

Edytor zgłasza typsteditor:ready, twoja strona odpowiada typsteditor:load, edytor zgłasza typsteditor:loaded, typsteditor:change przy rzeczywistych zmianach i typsteditor:save, gdy użytkownik zapisuje. Twoja strona może wysłać typsteditor:get (bieżący stan) lub typsteditor:save (naciśnięcie Zapisz). Zapis odbywa się wtedy przez twoje własne logowanie i sesję.

<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') {             // edytor jest gotowy: przekaż mu dokument
    ed.contentWindow.postMessage({
      type: 'typsteditor:load',
      name: 'Flyer',
      content: await (await fetch('/docs/flyer.typ')).text(),
      assets: { 'logo.png': 'data:image/png;base64,…' }   // opcjonalne obrazy i pliki danych
    }, ORIGIN);
  }
  if (m.type === 'typsteditor:change') document.title = '● not saved';   // rzeczywista zmiana
  if (m.type === 'typsteditor:save') {              // użytkownik kliknął „Zapisz”
    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';
  }
});

// Przycisk zapisu na twojej stronie: odpowiedź przychodzi jako typsteditor:save
function saveNow() { ed.contentWindow.postMessage({ type: 'typsteditor:get' }, ORIGIN); }
</script>

Asystent AI na twojej stronie: działa także w ramce. Z allow="clipboard-write" w iframe „Kopiuj prompt” korzysta bezpośrednio ze schowka (w przeciwnym razie edytor używa starego polecenia kopiowania albo pokazuje prompt do ręcznego skopiowania). Link wysłany przez AI nie dotrze do edytora osadzonego w innej stronie, więc edytor prosi AI i użytkownika o wklejenie całej odpowiedzi AI do edytora - albo o otwarcie edytora we własnym oknie.

3. We własnym oknie

window.open("https://typst.giit.ch/?embed=window", "typsteditor-17") otwiera pełny edytor we własnym oknie, który wymienia te same wiadomości z window.opener. Linki od AI docierają do niego tam. typsteditor:load może też zawierać context: { host, title, rules } - prompt dla AI mówi wtedy, gdzie należy dokument, i stosuje twoje zasady - oraz hook: { url, token, assets: false }, webhook tylko dla tego dokumentu, który nigdy nie jest zapisywany. Zamknięcie okna z niezapisanymi zmianami wysyła typsteditor:closing. typsteditor:pdf prosi o PDF dokumentu strony i otrzymuje go z powrotem jako data URI, utworzony przez kompilator Typst z prawdziwym tekstem do zaznaczania.

4. AI przez twój własny serwer

Przekaż edytorowi własny prompt, adres w twojej witrynie i klucz dla tej sesji edytora. Okno AI pokazuje wtedy „Połączono z” twoją witryną, to, co przekazujesz AI, oraz wybór: zmienić bieżący dokument lub utworzyć nowy; Kopiuj prompt łączy to wszystko. AI wysyła swój wynik z kluczem na twój serwer, a twoja strona otwiera go w edytorze - nowy dokument otwiera się osobno i zostaje w przeglądarce użytkownika. Jeden klucz na sesję edytora: pozostaje ważny, dopóki edytor jest otwarty, a edytor prosi o niego przez typsteditor:key-request tylko wtedy, gdy go nie ma. Edytor nigdy sam nie wysyła klucza i nigdy go nie zapisuje; adres musi być adresem https na twoim własnym hoście lub jego subdomenie.

const key = async () => (await fetch('/api/ai-key.php?doc=17')).json();   // jeden klucz na sesję edytora
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);
// zapamiętaj id z typsteditor:loaded i ignoruj change/save/closing z innym id
// tylko gdy edytor nie ma klucza:
if (m.type === 'typsteditor:key-request') { const k = await key(); ed.contentWindow.postMessage({ type: 'typsteditor:ai', key: k.key }, ORIGIN); }
// dopóki edytor jest otwarty, informuj serwer co minutę; zamknięcie edytora lub strony unieważnia klucz
setInterval(() => fetch('/api/ai-key.php?alive=' + k.key.slice(0, 8)), 60000);
// twój serwer ma wynik (polling, SSE …): target to "current" lub "new"
ed.contentWindow.postMessage({ type: 'typsteditor:load', name: 'Flyer', content: draft, from: 'ai', target }, ORIGIN);
<?php // api/ai-key.php - klucz tej sesji edytora zalogowanego użytkownika (wywołuje go twoja strona)
session_start();                                     // sprawdź, czy użytkownik może edytować ten dokument
$key = bin2hex(random_bytes(24));
$_SESSION['ai'][hash('sha256', $key)] = ['doc' => (int)$_GET['doc'], 'seen' => time()];  // lub w twojej bazie danych; ?alive= ponownie ustawia seen
echo json_encode(['key' => $key]);

<?php // api/ai-result.php - tu AI wysyła wynik (bez nagłówków CORS: AI wywołują go z serwera)
$key = preg_replace('/^Bearer\s+/', '', $_SERVER['HTTP_AUTHORIZATION'] ?? '');
$row = find_key(hash('sha256', $key));               // twoja baza danych: nieunieważniony, widziany w ciągu ostatnich 3 minut
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');   // twoja strona pokazuje go przez typsteditor:load
echo '{"ok":true}';

Twórz klucze z co najmniej 128 losowymi bitami, przechowuj tylko ich hash, wiąż każdy z zalogowanym użytkownikiem, dokumentem i tą sesją edytora, twórz jeden na sesję, utrzymuj go ważnym tylko wtedy, gdy twoja strona zgłasza sesję jako otwartą, i unieważniaj go, gdy edytor lub strona zostaną zamknięte.

Cały protokół jest opisany w llms.txt - przekaż go AI, a zbuduje połączenie dla twojego systemu. Edytor LaTeX działa tak samo z prefiksem latexeditor: - latex.giit.ch.

Najczęstsze pytania

Czy mój dokument jest gdzieś wysyłany?

Nie. Edytor i kompilator Typst działają w całości w przeglądarce. Dokumenty, obrazy i pliki nigdy nie są wysyłane na serwer, chyba że sam skonfigurujesz webhook do własnego serwera.

Czy to prawdziwy kompilator Typst?

Tak. Edytor uruchamia Typst 0.14 skompilowany do WebAssembly (typst.ts), więc strony i PDF są takie same jak z wiersza poleceń Typst. Jest ładowany raz (około 11 MB), a potem przechowywany przez przeglądarkę.

Jak uzyskać PDF?

Kliknij „Eksportuj”, wybierz PDF i kliknij „Pobierz”. PDF pochodzi wprost z kompilatora Typst, z prawdziwym tekstem, który można zaznaczać i przeszukiwać.

Czy mogę używać pakietów z Typst Universe?

Nie bezpośrednio: edytor nie ładuje niczego z innych serwerów, więc #import "@preview/…" zgłasza problem z nazwą pakietu. Pliki .typ pakietu można dodać do dokumentu w karcie Obrazy i importować je po nazwie pliku.

Jakie czcionki są dostępne?

Czcionki dostarczane z Typst: Libertinus Serif (domyślna), New Computer Modern z jej czcionką matematyczną oraz DejaVu Sans Mono do kodu. Dodaj własne pliki .otf lub .ttf do dokumentu i używaj ich przez #set text(font: "Name").

Jak dodać obrazy?

Przeciągnij lub wklej obraz do edytora albo dodaj go w karcie Obrazy po prawej. Jest przechowywany razem z dokumentem w przeglądarce i używany przez #image("name.png"). Pliki CSV, JSON, YAML i .bib działają tak samo.

Czy AI może pisać w Edytorze Typst?

Tak, każda AI - ChatGPT, Claude, Gemini, Copilot lub AI w twoim narzędziu programistycznym. Kliknij „Asystent AI”, potem „Kopiuj prompt”, wklej go do swojej AI i napisz, co ma napisać. AI odpowiada linkiem; kliknij go, a dokument pojawi się w edytorze. „Cofnij” cofa każdą zmianę.

Czy mogę używać edytora na własnej stronie?

Tak. Osadź go w iframe i wymieniaj dokumenty przez postMessage albo pozwól mu wysyłać każdą zapisaną wersję na twój serwer przez webhook. Przykłady znajdziesz w sekcji Edytor na własnej stronie.

Czy Edytor Typst coś kosztuje?

Nie. Edytor jest darmowy, bez reklam i bez rejestracji.