Recipes

Recipes are Markdown files in llms.txt format that describe a website's structure to the AI. They tell gyoza what pages exist, what interactive elements are on each page, and what each page does — so the AI can navigate and act with precision instead of guessing.

What are recipes?

A recipe is a single Markdown .txt file that acts as a sitemap for the AI. Based on the llms.txt standard, it contains structured metadata about a website:

  • Routes — what pages/URLs exist and what they're called
  • UI elements — buttons, inputs, links, and forms on each page, identified by CSS selectors
  • API endpoints — server endpoints the AI can call via fetch actions (optional)
  • Page descriptions — human-readable summaries of what each page contains and does

Think of a recipe like a map you hand to a new employee on their first day. Without it, they can still figure things out by looking around — but with the map, they know exactly where to go and what tools are available.

Because recipes are plain Markdown, they're naturally LLM-friendly — language models are trained on vast amounts of Markdown and process it with zero friction. No XML parsing needed.

How recipes enhance AI navigation

When a recipe is loaded for the current website, gyoza injects the entire manifest as context into the AI prompt. This gives the language model a complete picture of the site before it even looks at the current page's DOM.

With a recipe, the AI can:

  • Navigate directly — it knows the exact URL paths, so it can jump to any page in one step instead of clicking through menus
  • Find elements reliably — CSS selectors in the recipe point to specific buttons and inputs, eliminating guesswork
  • Understand context — page descriptions tell the AI what a page is for, even if the UI is in another language
  • Call APIs — if the recipe lists API endpoints, the AI can use fetch actions to get or submit data programmatically
  • Reduce LLM calls — fewer "explore and discover" steps means the AI completes tasks faster and cheaper

Manifest mode vs no-manifest mode

gyoza operates in two modes depending on whether a recipe is available:

With recipe (manifest mode)

  • Full site structure injected as context
  • AI knows all routes, elements, and APIs upfront
  • Can navigate directly to any page
  • Uses stable CSS selectors from the recipe
  • Faster task completion, fewer LLM round-trips
  • Works well even on non-English sites

Without recipe (no-manifest mode)

  • AI reads the live DOM of the current page
  • Discovers navigation links by scanning the page
  • May need multiple steps to find the right page
  • Generates selectors on the fly from visible elements
  • Still works, but slower and less reliable
  • Better for simple tasks or one-off sites

Both modes are fully functional. Recipes are an optimization — they make the AI smarter and faster on sites you use regularly, but gyoza never requires a recipe to work.

The llms.txt recipe format

Recipes follow the llms.txt standard — a Markdown-based format designed for providing LLM-friendly context. gyoza extends it with specific sections for Routes, UI Elements, and Page Descriptions. Here is the complete structure:

# Site Name

> domain: example.com | prefix: /optional-prefix

Short description of what the site does.

## Routes

- [Home](/): Landing page
- [Products](/products): Product listing

## UI Elements

- `#search` input "Search bar" on /
- `.nav-cart` link "Cart" on /

## API Endpoints

- POST /api/search: Search products
- GET /api/cart: Get cart contents

## Page Descriptions

- /: Landing page with hero section, featured products, and search bar
- /products: Filterable product grid with category sidebar and sort options

Section reference

Header — site identity

The recipe starts with an H1 heading (the site name), a blockquote with domain and optional prefix, and a short description paragraph.

  • # Site Name — the name of the site. The AI uses this for context.
  • > domain: example.com | prefix: /app — the domain this recipe targets (used for auto-matching) and an optional path prefix.
  • Description paragraph — a brief summary of what the site does.

## Routes — site navigation

A list of all navigable pages using the llms.txt link format. Each entry follows the pattern:

- [Page Name](/path): Description of the page
  • Link text — the human-readable page name. Can be in any language.
  • URL — the path for this route.
  • Description — short description of the page's purpose.
Tip: List every page a user might need to visit. The AI uses this list to decide where to navigate. If a page is missing from the routes, the AI can still discover it by reading links on the current page, but having it listed is faster and more reliable.

## UI Elements — interactive elements

Describes buttons, inputs, links, and forms on each page. Each entry follows the pattern:

- `css-selector` type "label" on /route
  • `selector` — a CSS selector that uniquely identifies this element. Prefer #id selectors when possible.
  • type — the kind of element: button, link, input, form, select, or toggle.
  • "label" — human-readable label. For non-English UIs, include an English translation in parentheses.
  • on /route — which page this element appears on.

## API Endpoints — server APIs (optional)

Lists REST API endpoints the AI can call using fetch actions. Most recipes don't need this section. Each entry follows the pattern:

- METHOD /api/path: Description

## Page Descriptions — page summaries

Provides richer context about each page's layout and content. While Routes have short descriptions, Page Descriptions give the AI a fuller picture. Each entry follows the pattern:

- /route: Detailed summary of what this page looks like and does.
Tip: Page descriptions are especially valuable for non-English sites. Even if the UI is entirely in Japanese, a good English summary helps the AI understand the page and translate instructions for the user.

Example: Ginko bank recipe

The Ginko demo is a Japanese banking application. Here is its complete recipe:

# Ginko Bank

> domain: localhost:4321 | prefix: /demos/ginko

Japanese bank portal with deposit, withdraw, transaction history, and account overview.

## Routes

- [ホーム](/demos/ginko): Bank home page with announcements and quick links
- [口座概要](/demos/ginko/account): Account overview showing balance and recent transactions
- [入金](/demos/ginko/deposit): Deposit form with amount input
- [出金](/demos/ginko/withdraw): Withdrawal form with amount and destination
- [取引履歴](/demos/ginko/history): Transaction history with filterable table

## UI Elements

- `a[href='/demos/ginko/deposit']` link "入金する (Deposit)" on /demos/ginko
- `a[href='/demos/ginko/withdraw']` link "出金する (Withdraw)" on /demos/ginko
- `a[href='/demos/ginko/history']` link "取引履歴を見る (View History)" on /demos/ginko
- `a[href='/demos/ginko/account']` link "口座概要 (Account Overview)" on /demos/ginko
- `#amount` input "金額(円)(Amount in JPY)" on /demos/ginko/deposit
- `#memo` input "メモ (Memo, optional)" on /demos/ginko/deposit
- `#deposit-form button[type='submit']` button "入金を確認 (Confirm Deposit)" on /demos/ginko/deposit
- `#amount` input "金額(円)(Amount in JPY)" on /demos/ginko/withdraw
- `#destination1` input "送金先口座番号 (Destination account number)" on /demos/ginko/withdraw
- `#withdraw-form button[type='submit']` button "出金を確認 (Confirm Withdrawal)" on /demos/ginko/withdraw

## Page Descriptions

- /demos/ginko: Japanese bank landing page. Shows bank name, welcome message, latest
  announcements, and quick action buttons for deposit, withdraw, and viewing transaction
  history. All text is in Japanese.
- /demos/ginko/account: Account overview page. Displays current account balance in JPY,
  account number, and a list of recent transactions with date, description, and amount.
- /demos/ginko/deposit: Deposit page. Contains a form with an amount field (in JPY)
  and a confirm button.
- /demos/ginko/withdraw: Withdrawal page. Contains a form with amount field (in JPY),
  destination account field, and a confirm button.
- /demos/ginko/history: Transaction history page. Shows a table of all transactions
  with columns: date, type, description, and amount.

Notice a few things about this recipe:

  • Japanese names with English translations — the route names use the Japanese UI labels, while labels on UI elements include English translations in parentheses. This helps the AI map between what the user says in English and what appears on screen in Japanese.
  • Stable selectors — the deposit form uses #amount and #memo (ID selectors), which are unlikely to change. Navigation links use attribute selectors like a[href='/demos/ginko/deposit'], which are also stable.
  • Plain Markdown — no XML parsing required. The AI reads this as natural Markdown, which is how it was trained to process information.
  • No API endpoints — this recipe doesn't list any because the Ginko demo is a purely client-side app. The ## API Endpoints section is optional.

Testing your recipe

To test a recipe you've written:

  1. Install the gyoza extension — get it from the Chrome Web Store or load the unpacked extension from the GitHub repo.
  2. Open the extension settings — click the gyoza icon in the toolbar and go to Settings.
  3. Import your recipe — use the "Import Recipe" button and select your .txt or .md recipe file.
  4. Navigate to your site — go to the website the recipe is for. The extension will automatically match the recipe by domain.
  5. Ask the AI to do something — try a task like "go to the settings page" or "fill in the search box with 'test'". Watch whether it uses the recipe's selectors and routes correctly.
  6. Check for broken selectors — if the AI can't find an element, the selector in your recipe might be wrong. Open DevTools, use the Elements panel, and verify the selector matches exactly one element.
Quick selector test: Open the browser console and run document.querySelector('your-selector') to verify it matches the right element. If it returns null, the selector is wrong.

Tips for writing good recipes

Use stable CSS selectors

The most common reason a recipe breaks is that CSS selectors no longer match the DOM. Here's a selector preference order:

  1. #id — best. IDs are unique and rarely change.
  2. [data-testid="..."] — great if the site uses test attributes.
  3. a[href='/path'] — good for navigation links.
  4. .specific-class — OK if the class is semantic, not generated (avoid .css-1a2b3c).
  5. form button[type='submit'] — acceptable compound selectors.
  6. div > div > span:nth-child(3) — avoid. Fragile and breaks with any layout change.

Describe pages from the user's perspective

Page descriptions should answer: "What would a user see and do on this page?" Don't describe implementation details. Instead of "React component rendering a list," write "A scrollable list of recent orders with date, status, and total price."

Include all interactive elements

Every button, link, input, and form the user might want to interact with should be in the recipe. The AI will only use elements it knows about from the recipe (in manifest mode) or can discover in the DOM (which is slower). Missing an element means the AI has to fall back to DOM scanning for that interaction.

Keep descriptions concise but informative

The entire recipe is injected into the AI prompt as context. Long-winded descriptions waste tokens and can push important content out of the context window. Aim for 1-2 sentences per page description and short, clear labels for UI elements.

Test on the real site

Always test your recipe on the actual website. Selectors that work in development may break in production if the build process changes class names or restructures the DOM. Test with the actual deployed version.