A prompt you only use once can live in the editor. A prompt you reuse — translate, extract, review, answer from retrieved context — should be a template with the moving parts marked.
Templates stores those patterns locally. Built-in templates cover writing, development, RAG, agents, and data extraction. Anything you save yourself stays in this browser, not in an account.
The only placeholder syntax
Variables are double braces with a plain name:
Translate the following text from {{source_lang}} to {{target_lang}}.
Rules:
- Preserve meaning and formatting
- Keep code, IDs, and product names unchanged
- Output only the translation
Text:
{{text}}
Names are simple tokens such as source_lang or text. The variable panel lists every name it finds. Fill the inputs and the preview replaces them. Unfilled names stay as {{text}} so you can see what is still open.
That same syntax is what Variable batch test and the linter understand. Do not invent a second style (${text}, <text>, or single braces) in the same draft or the batch table will miss the column.
Start from a built-in, then save your own
The library is grouped by job. A few that cover most API work:
| Template | Mode | What varies |
|---|---|---|
| Translate / Summarize | Text | Language, tone, source text |
| Code review | ChatML | Language, focus, and the code block |
| RAG system | ChatML | Domain, language, context, question |
| Data extract | Text | Output format, field list, source text |
Open one, fill the variables, and send it to the editor when you want token counts and export. If you change the wording, save a custom template. Custom templates are JSON in localStorage. They are not synced, and they disappear with a cleared site storage — export a copy if the wording is the one you ship.
Chat templates keep system and user as separate messages. Text templates are a single buffer. Pick the mode that matches how you will call the API. The ChatML editor article shows why that split matters for export.
Batch-test rows before you call the API
One filled preview proves the template runs. It does not prove the wording survives ten different inputs.
- Copy the template, placeholders included, into Variable batch test.
- The table builds a column per name (
source_lang,target_lang,text, …). - Add a row per case, or paste TSV.
- Read each preview. A warning means a placeholder was still unresolved.
- Open a row in the editor when you want a token count or ChatML export for that case.
A useful first batch for the translation template is three rows: a short UI string, a paragraph that contains a product name, and a snippet of code that must not be translated. If row 3 rewrites identifiers, the rule line is weak — edit the template, not the row.
For retrieval, the batch is usually one stable system template and many {{question}} / {{context}} pairs. Keep the rules identical across rows so you are testing the question, not accidentally testing a rewritten system prompt. That layout is spelled out in Build a RAG system prompt.
Check leftovers before export
Lint flags {{names}} that are still in the text, and braces that are not valid names. Run it after you fill a template and before you copy JSON. A leftover {{context}} shipped to production is a silent empty retrieval.
Other checks on the same page: missing or empty system message, empty user turn, broken JSON fences, duplicate lines, and a character count that is already past a soft or hard threshold. Lint does not call a model. It only reads the draft.
Keep the release copy
After the batch looks right, save a version snapshot labeled Release, then export. The template can keep its placeholders for the next task. The snapshot is the filled prompt you actually sent.