Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
361de46
chore(docs): upgrade docs dependencies to their latest releases
joshistoast Oct 26, 2026
b807023
feat(docs): restyle the docs on the app's v7 theme
joshistoast Oct 26, 2026
c7486c1
feat(docs): organize the sidebar into topics with a switcher
joshistoast Oct 26, 2026
3e67bd8
feat(docs): add the shared header, page actions and feedback
joshistoast Oct 26, 2026
e871d9f
feat(docs): add a topic-scoped search modal with settings results
joshistoast Oct 26, 2026
c5dfaaa
feat(docs): add an OS and GPU setup picker to the manual install guide
joshistoast Oct 26, 2026
33d8cff
feat(docs): rebuild the download page around the latest launcher release
joshistoast Oct 26, 2026
27ed223
feat(docs): rebuild the home page with an interactive tour and showcase
joshistoast Oct 26, 2026
dea393d
feat(docs): generate an app search index from the docs build
joshistoast Oct 26, 2026
d07ccce
feat(palette): search the docs from the command palette
joshistoast Oct 26, 2026
9b781c8
fix(docs): repair relative links to moved pages
joshistoast Oct 26, 2026
d82b2c4
feat(docs): add German, Spanish and Hindi locales
joshistoast Oct 26, 2026
5dbbbd0
feat(docs): serve interface strings from the translation catalog
joshistoast Oct 26, 2026
d7196cc
feat(docs): make the home page copy translatable
joshistoast Oct 26, 2026
fed95dd
feat(docs): check translated pages and strings against English
joshistoast Oct 26, 2026
08886e3
feat(docs): sync docs translations with Crowdin
joshistoast Oct 26, 2026
2664eac
fix(docs): correct step counts, indexing, NF4 support and LTX-2 headings
joshistoast Oct 27, 2026
4f08d3e
docs(multi-user): rewrite the admin and user guides
joshistoast Oct 27, 2026
3c9555d
feat(docs): add annotated screenshots to the Intermediates and Models…
joshistoast Oct 27, 2026
2679e61
feat(docs): show upscaling with a before/after slider and pipeline di…
joshistoast Oct 27, 2026
db1915c
feat(docs): add a memory options picker and restructure the optimizat…
joshistoast Oct 27, 2026
e50acda
feat(docs): list community node packs in a searchable grid
joshistoast Oct 27, 2026
ce1bfb5
fix(docs): restore the hero screenshot's gradient border
joshistoast Oct 27, 2026
dffec4a
docs: use the jellyfish screenshot on the home page and Canvas introd…
joshistoast Oct 27, 2026
bd05e2a
fix(docs): show model family cards without image placeholders
joshistoast Oct 27, 2026
8bc5bc7
Merge remote-tracking branch 'origin/main' into feat/docs-v7
joshistoast Oct 27, 2026
f18a4e4
feat(docs): publish weekly challenge winners on the showcase
joshistoast Oct 27, 2026
e01009d
docs: some community challenge submissions
joshistoast Oct 27, 2026
2b0d289
fix(docs): reconcile current guides with redesign
joshistoast Oct 29, 2026
883b694
fix(docs): keep search aligned with current model guides
joshistoast Oct 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
22 changes: 22 additions & 0 deletions .github/ISSUE_TEMPLATE/DOCS_ISSUE.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Documentation issue
description: Report a mistake or a gap on a documentation page
title: '[docs]: '
labels: ['documentation']

body:
- type: input
id: page
attributes:
label: Page
description: The documentation page with the problem. The "Report an issue" link on each page fills this in.
placeholder: https://v7.invoke.ai/...
validations:
required: true

- type: textarea
id: problem
attributes:
label: What is wrong or missing?
description: Quote the passage if it helps, and tell us what you expected to find.
validations:
required: true
55 changes: 55 additions & 0 deletions .github/ISSUE_TEMPLATE/SHOWCASE.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Showcase submission
description: Submit artwork you made with Invoke for the showcase on the docs site
title: '[showcase]: '

body:
- type: markdown
attributes:
value: |
Thanks for sharing your work. A maintainer reviews each submission before it appears on the [showcase](https://v7.invoke.ai/showcase/), credited to you.

- type: textarea
id: artwork
attributes:
label: Artwork
description: Drag your image into this box, or paste it. PNG, JPEG or WebP, ideally at least 2000 px on the long side. Upload the original, not a screenshot.
validations:
required: true

- type: input
id: title
attributes:
label: Title
validations:
required: true

- type: input
id: artist
attributes:
label: Artist name
description: The name to credit, exactly as it should appear.
validations:
required: true

- type: input
id: artist-link
attributes:
label: Artist link
description: Optional. Your portfolio, website or social profile.
placeholder: https://

- type: textarea
id: made-with
attributes:
label: Model and workflow
description: Optional. The model you used, such as FLUX.2 Klein, and anything notable about how you made it.

- type: checkboxes
id: permission
attributes:
label: Permission
options:
- label: I made this image.
required: true
- label: I grant Invoke permission to display it on the Invoke docs site with credit; I can ask for removal anytime.
required: true
14 changes: 14 additions & 0 deletions .github/workflows/deploy-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,14 @@ jobs:
filters: |
docs:
- '.github/workflows/deploy-docs.yml'
- 'crowdin.yml'
- 'docs/**'
# The docs color tokens are generated from the app's theme.
- 'invokeai/frontend/webv2/src/platform/ui/theme/themes.ts'
# docs/src/assets/v7-logo.webp must match the app's logo (docs/src/lib/app-assets.test.mjs).
- 'invokeai/frontend/webv2/src/assets/V7Logo.webp'
# The app's committed copy of the docs search index must match the build (check-app-search-index).
- 'invokeai/frontend/webv2/src/workbench/palette/docsSearchIndex.json'
- 'scripts/generate_docs_json.py'
- 'invokeai/app/**'
- 'invokeai/backend/**'
Expand All @@ -66,6 +73,9 @@ jobs:
steps:
- name: checkout
uses: useblacksmith/checkout@25227e61ff9dafe400e22fa487b673eac4e4409a # v1.8.1
with:
# Full history: each page's "Updated" date comes from its last commit.
fetch-depth: 0

# Python (needed for generate-docs-data)
- name: setup uv
Expand Down Expand Up @@ -118,6 +128,10 @@ jobs:
ENABLE_ANALYTICS: ${{ github.ref == 'refs/heads/main' }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: verify app search index
run: pnpm run check-app-search-index
working-directory: docs

- name: verify deploy output
run: pnpm run check-deploy-output
working-directory: docs
Expand Down
42 changes: 42 additions & 0 deletions crowdin.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Crowdin's GitHub integration reads this file from main, uploads the English sources and opens a pull request with
# the translations. The credentials are only for running the Crowdin CLI locally. docs/README.md has the runbook.
project_id_env: CROWDIN_PROJECT_ID
api_token_env: CROWDIN_PERSONAL_TOKEN
preserve_hierarchy: true

# Only the user-facing docs trees. development/ and contributing/ stay English and show as fallbacks in every locale.
# A translation lands at docs/src/content/docs/<locale>/<the English path>; the site builds the locales that
# docs/src/config/locales.mjs lists. MDX pages use the MDX v2 parser; .md pages are plain Markdown, where braces are
# text. A tree has an .md entry only while it has .md pages: the Crowdin CLI fails on a pattern that matches nothing.
files:
- source: '/docs/src/content/docs/index.mdx'
translation: '/docs/src/content/docs/%two_letters_code%/%original_file_name%'
type: mdx_v2

- source: '/docs/src/content/docs/start-here/**/*.mdx'
translation: '/docs/src/content/docs/%two_letters_code%/start-here/**/%original_file_name%'
type: mdx_v2
ignore: ['/docs/src/content/docs/**/assets/**']

- source: '/docs/src/content/docs/Users Guide/**/*.mdx'
translation: '/docs/src/content/docs/%two_letters_code%/Users Guide/**/%original_file_name%'
type: mdx_v2
ignore: ['/docs/src/content/docs/**/assets/**']
- source: '/docs/src/content/docs/Users Guide/**/*.md'
translation: '/docs/src/content/docs/%two_letters_code%/Users Guide/**/%original_file_name%'
ignore: ['/docs/src/content/docs/**/assets/**']

- source: '/docs/src/content/docs/configuration/**/*.mdx'
translation: '/docs/src/content/docs/%two_letters_code%/configuration/**/%original_file_name%'
type: mdx_v2
ignore: ['/docs/src/content/docs/**/assets/**']

- source: '/docs/src/content/docs/troubleshooting/**/*.mdx'
translation: '/docs/src/content/docs/%two_letters_code%/troubleshooting/**/%original_file_name%'
type: mdx_v2
ignore: ['/docs/src/content/docs/**/assets/**']

# The site's UI strings. `_one`/`_other` keys are i18next plural forms; Crowdin exports each language's own.
- source: '/docs/src/content/i18n/en.json'
translation: '/docs/src/content/i18n/%two_letters_code%.json'
type: i18next_json
106 changes: 106 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,107 @@
# Invoke AI Documentation

The docs site at [v7.invoke.ai](https://v7.invoke.ai), built with Astro Starlight. Paths below are relative to `docs/`; `crowdin.yml` is at the repository root.

Contributor guide: [Documentation](src/content/docs/development/Documentation/index.mdx) (dev server, adding pages, builds, tests).

Community content: [showcase artwork](src/content/showcase/README.md), [weekly challenge winners](src/content/challenges/README.md) and [community node packs](src/content/community-nodes/README.md).

Toolchain: Node 22.23.4 or newer (`engines` in `package.json`; Astro needs it) and pnpm 10, run from this directory.

## Translations

English is the source of truth. Translators work in the Crowdin project ([crowdin.com/project/invoke](https://crowdin.com/project/invoke), `CROWDIN_PROJECT_URL` in `src/config/locales.mjs`; confirm this URL once the project is set up, since `src/content/docs/contributing/translations.md` links it too). Crowdin's GitHub integration reads `crowdin.yml`, uploads the English sources from `main` and opens a pull request with the translations. There is no Crowdin workflow or repository secret.

The site builds the locales in `src/config/locales.mjs`: English at the root, and `de`, `es` and `hi` under `/<locale>/`. A page without a translation is served in English with Starlight's "not translated yet" notice. A translated page's footer link reads **Translate this page** and opens Crowdin instead of GitHub.

### What Crowdin owns

- `src/content/docs/{de,es,hi}/**`: translated pages at the English page's path.
- `src/content/i18n/{de,es,hi}.json`: translated interface strings.

Don't edit these by hand: the next sync overwrites them. Fix the English source, or the translation in Crowdin.

Crowdin gets the home page (`src/content/docs/index.mdx`), `start-here/`, `Users Guide/`, `configuration/`, `troubleshooting/` and `src/content/i18n/en.json`. `development/` and `contributing/` stay English and show as fallbacks in every locale. Releases, download and showcase pages exist only at the root, in English.

Translations are not marked `linguist-generated` in `.gitattributes`: translated MDX compiles into the site, so its diffs stay expanded for review.

### Adding pages and UI strings

- **Pages.** A new `.mdx` page in a translated tree reaches Crowdin on the next sync. A tree's first `.md` page needs an `.md` entry in `crowdin.yml` (the Crowdin CLI fails on patterns that match nothing, so only `Users Guide/` has one). A new top-level docs directory goes into `ENGLISH_TREES` in `src/lib/translation-checks.mjs`, and into `crowdin.yml` if it should be translated.
- **UI strings.** Add the English string to `src/content/i18n/en.json` and read it with `Astro.locals.t('key')`, or with the `Trans` component (`src/lib/components/Trans.astro`) when it contains markup such as `<link>…</link>`. Placeholders are i18next `{{name}}`. Plurals are `key_one`/`key_other`, read with `t('key', { count })`, or in a client script with `pluralForms` (`src/lib/i18n.mjs`). `src/lib/i18n-keys.test.mjs` fails when code uses a key `en.json` lacks, or `en.json` has a key nothing uses. Give short or ambiguous strings a context note in Crowdin (below).

### Adding a locale

1. Add the language as a target in Crowdin.
2. Add a lowercase key to `locales` in `src/config/locales.mjs`, with the language's own name as `label` and its BCP 47 tag as `lang` (for example `'zh-cn': { label: '简体中文', lang: 'zh-CN' }`).
3. For a regional variant, map Crowdin's code to that lowercase directory, because `%two_letters_code%` drops the region. Add this to every `files` entry in `crowdin.yml`:

```yaml
languages_mapping:
two_letters_code:
zh-CN: zh-cn
```

Nothing else changes: Starlight's routes, the language menu, `scripts/verify-deploy-output.mjs` and the translation checks all read `locales.mjs`. Check in a build that the site font covers the script (Inter has no Devanagari, for example).

### Reviewing a Crowdin pull request

Docs CI runs `pnpm test`, the build (links included) and the deploy checks on it. `src/lib/translation-checks.mjs` parses each translated page as the build does (Astro's frontmatter parser, then MDX or Markdown with the build's GitHub Flavored Markdown and Starlight directive plugins) and compares it with the English page at the same path. A translation may change prose, comments and code samples; anything else fails with the file and the offending key, element or value:

- a directory in `src/content/docs/` or a file in `src/content/i18n/` for a locale `locales.mjs` doesn't configure;
- a file in a locale directory that isn't a page, or a page with no English page at the same path;
- a page that doesn't parse;
- `import`/`export` code that differs from English;
- a `{…}` expression, JSX element, aside or other container directive (`:::note`), attribute or attribute value the English page lacks. Prose attributes (`alt`, `aria-label`, `description`, `label`, `title`) may change but take no `<`, since Starlight renders card titles as HTML;
- a link, image or reference URL the English page lacks, autolinked URLs included (the `#fragment` may change);
- raw HTML the English page lacks (in `.md` pages);
- frontmatter beyond `title`, `description`, `hero.title`, `hero.tagline`, `sidebar.label` and `hero.actions[].text` that differs from English, such as `head`, `template` or a link, or any of those containing `<`;
- a string in `<locale>.json` with a key `en.json` lacks (plural messages may use any of `_zero`, `_one`, `_two`, `_few`, `_many`, `_other`), different `{{placeholders}}` or tags, or `<script`, `on…=` or `javascript:`.

Fix failures in Crowdin, not in the pull request. The checks don't judge language, so still read for meaning, tone and product names left in English (Invoke, node and model names), for edited commands and values in code samples, and for the rendering in a preview build (`pnpm build && pnpm preview`), especially Hindi.

Before merging the first real translation, run `pnpm test` on the first sync's pull request, or locally on `pnpm dlx @crowdin/cli download --pseudo` output (run from the repository root; it writes into the locale directories, so delete them afterwards). It confirms that Crowdin's MDX v2 export leaves imports, components and expressions byte-identical, which every later check relies on.

### Crowdin parser settings

`crowdin.yml` sets the file types: MDX v2 (`mdx_v2`) for `.mdx`, Markdown for `.md` and i18next JSON for `en.json`, so `_one`/`_other` keys become plural forms. In Crowdin's Settings → Parser configuration, exclude the frontmatter that isn't prose, for both MDX and Markdown:

`lastUpdated`, `template`, `slug`, `sidebar.order`, `sidebar.hidden`, `pagefind`, `draft`, `alsoListedIn`, `hero.actions.link`, `hero.image.file`

### Translator context notes

After the first sync, paste these into each string's context in Crowdin.

| Key | Note |
| --- | --- |
| `search.scopeChipsIntro` | "In", shown before the search scope chips. |
| `search.scopeChangeStatus` | Screen-reader announcement: `{{scope}}` is the scope's name, `{{results}}` the result count message. |
| `search.settingDefault` | Pill on a settings result: "default" and the setting's default value. |
| `search.settingsGroup` | Heading of settings results. Keep `invokeai.yaml`. |
| `keyboardHint.*` | One short verb each, shown after a key symbol. |
| `languageMenu.accessibleLabel` | `{{label}}` is "Select language", `{{code}}` the locale code, `{{language}}` the language's name. |
| `settingsReference.envVar` | "Env", short for environment variable. |
| `settingsReference.allowedValues` | A list of allowed values follows. |
| `topics.group.*` | One-word imperative group headings. |
| `pageActions.copyDone`, `pageActions.copyFailed` | Short button states. |
| `page.updated`, `setupPicker.summary`, `setupPicker.summaryNotes`, `footer.credit`, `pageFeedback.reportPrompt` | Keep the `<time>`, `<setup>` and `<link>` tags around the matching words. |
| `nav.siteNavLabel` | Landmark name for screen readers. |
| `sidebar.group.*` | Navigation section names. |
| `home.hero.announcement` | Keep "Invoke V7". |
| `home.*.eyebrow` | Short label above a home page section heading. |
| `home.directory.*.kicker` | One-word verbs. |
| `home.cta.platformsAndLicense` | Keep the OS names and "Apache 2.0". |
| `home.install.body` | Keep the three tags; their order may change. |
| `home.community.body` | Keep the `<link>` tag and the maintainers' names. |
| `home.challenge.*` | The home page's teaser for the latest weekly art challenge on Discord. `{{week}}` is the challenge's number; the places label the winners' thumbnails. |
| `whatsNew.*.body` | Keep node and model names. |
| `modelFamilies.licenseTag`, `modelFamilies.vramTag` | `<srOnly>` text is read only by screen readers. Keep "GB+". |
| `modelFamilies.format.singleFile` | A model file format, listed beside GGUF and int8: one checkpoint file. |
| `imageCompare.valueText` | A slider's spoken value: `{{before}}` and `{{after}}` are percentages, `{{beforeLabel}}` and `{{afterLabel}}` the two images' labels, such as "Before" and "After". |
| `workflowDemo.field` | `{{field}}` and `{{node}}` stay English mock names. |
| `workflowDemo.connected`, `workflowDemo.disconnected` | `{{source}}` and `{{target}}` are filled with the `workflowDemo.field` message. |
| `communityNodes.manualInstallNote` | Keep the `<code>` tags; `nodes` and `__init__.py` stay as they are. |
| `communityNodes.shown_*` | `{{shown}}` packs match the filters, of `{{count}}` in all; the plural form follows `{{count}}`, the total. |
| `communityNodes.copyDone`, `communityNodes.copyFailed` | Short button states. |
| `communityNodes.byAuthor` | `{{author}}` is a GitHub or GitLab user name. |
| `communityNodes.dependencies`, `communityNodes.manualInstall` | Short badge text on a node pack card. |
Loading
Loading