---
title: "Translation Coverage"
description: "Per-language completion rings and a focused tree of pages still missing translations – Kirby 5 only."
canonical_url: "https://kirby.tools/docs/content-translator/panel/translation-coverage"
---

# Translation Coverage

> Per-language completion rings and a focused tree of pages still missing translations – Kirby 5 only.

Open `/panel/languages` (or the Languages icon in the Panel topbar) to see the coverage dashboard. Each language shows a completion ring and a list of incomplete pages – click any entry to jump straight to the Panel view that's missing content.

![Translation Coverage view in the Languages panel showing per-language completion rings and a Pages to Translate tree with branch counters and language-code tags for missing translations](/img/kirby-content-translator-translation-coverage.png)

## What You See

**Translation Coverage**: one ring per non-default language, showing the percentage of translatable fields that have content. The label below each ring reports how many pages are still incomplete (e.g. `4 incomplete pages`), or `All pages translated` once a language is complete. A language at 100% is highlighted as positive.

**Pages to Translate**: a tree of pages that have at least one missing language. Branches collapse to keep the list compact: only incomplete pages and their ancestors are shown. Each entry links straight to its Panel view so you can fix it in one click.

If everything is translated, the section is hidden entirely – the rings (all at 100%, themed positive) are the only signal you need.

## How Coverage Is Calculated

A field counts toward the totals when two conditions are met: your blueprint marks it translatable (or it's translatable by default for its field type), and the default language has content for that field. It counts as translated if its value in the secondary language is not empty. Only top-level fields are counted – a block or structure counts once, as a whole.

The dashboard spans the whole site, so it reads `fieldTypes`, `includeFields`, and `excludeFields` from `config.php` alone. Narrowing those per blueprint changes what a view button translates, but not what the rings report.

<note>

Default-language content is read without fallback when calculating coverage. A secondary-language content file that doesn't exist counts as zero translated fields, not as a copy of the default language.

</note>

<note>

A page where every translatable field is empty in the default language is omitted from the dashboard – there's nothing to translate against.

</note>

The default language itself is excluded from the rings – it's the source, not a target.

## Configuration

The dashboard audits `site()->index()` by default. Both the scope and the dashboard itself are controlled by the `coverage` option.

### Scoping the Audit

Pass a `pages` closure returning any `Pages` collection. Use it when parts of the site aren't editorial content – a large archive, generated pages, or a section no one translates:

```php [config.php]
return [
    'johannschopplich.content-translator' => [
        'coverage' => [
            'pages' => fn () => page('blog')->children()->listed()
        ]
    ]
];
```

<note>

Scoping changes what the rings measure, not just what the tree lists. A ring reports coverage across the pages you selected, so narrowing the scope raises the percentage.

</note>

### Disabling the Dashboard

Set the option to `false` to remove the coverage view from `/panel/languages` entirely:

```php [config.php]
return [
    'johannschopplich.content-translator' => [
        'coverage' => false
    ]
];
```

<tip>

Coverage results are cached and invalidated automatically when pages, the site, or languages change. Disabling is about the view, not about performance.

</tip>

### Caching

The plugin registers its own cache, active by default and shared by the coverage rings and the page tree. Point it at another driver, or turn it off entirely, through Kirby's [cache options](https://getkirby.com/docs/guide/cache):

```php [config.php]
return [
    'johannschopplich.content-translator' => [
        'cache' => [
            'type' => 'apcu'
        ]
    ]
];
```

<note>

With `'cache' => false` every coverage ring is recomputed per request, which walks the whole page index. Prefer `coverage: false` when the goal is to remove the view.

</note>

---

Every page of this site as Markdown: <https://kirby.tools/sitemap.md>
