PHPackages                             johannschopplich/kirby-lingohub - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Localization &amp; i18n](/categories/localization)
4. /
5. johannschopplich/kirby-lingohub

ActiveKirby-plugin[Localization &amp; i18n](/categories/localization)

johannschopplich/kirby-lingohub
===============================

Lingohub translation service integration for Kirby CMS

1.3.1(3mo ago)3701[1 issues](https://github.com/johannschopplich/kirby-lingohub/issues)MITPHP

Since Jan 22Pushed 3w ago2 watchersCompare

[ Source](https://github.com/johannschopplich/kirby-lingohub)[ Packagist](https://packagist.org/packages/johannschopplich/kirby-lingohub)[ Docs](https://github.com/johannschopplich/kirby-lingohub#readme)[ Fund](https://kirby.tools)[ RSS](/packages/johannschopplich-kirby-lingohub/feed)WikiDiscussions main Synced today

READMEChangelog (10)Dependencies (8)Versions (21)Used By (0)

[![Kirby Lingohub preview](./.github/kirby-lingohub.png)](./.github/kirby-lingohub.png)

Kirby Lingohub
==============

[](#kirby-lingohub)

The Kirby Lingohub plugin integrates the [Lingohub](https://lingohub.com) translation service into your Kirby website. The plugin allows you to upload content from Kirby to Lingohub for translation and download the translations back to Kirby. It handles the whole serialization and deserialization process, including complex field types like blocks, layouts, structures, and objects – even blocks nested within custom blocks.

Note

For this plugin to work, you need to have a Lingohub account and a project set up. You can create a free account at [Lingohub](https://lingohub.com/).

Requirements
------------

[](#requirements)

- Kirby 4 or Kirby 5

Kirby is not free software. However, you can try Kirby and the Starterkit on your local machine or on a test server as long as you need to make sure it is the right tool for your next project. … and when you're convinced, [buy your license](https://getkirby.com/buy).

Installation
------------

[](#installation)

### Composer

[](#composer)

```
composer require johannschopplich/kirby-lingohub
```

### Download

[](#download)

Download and copy this repository to `/site/plugins/kirby-lingohub`.

Getting Started
---------------

[](#getting-started)

### 1️⃣ Kirby Language Configuration

[](#1️⃣-kirby-language-configuration)

Set up a multi-language Kirby site. For each desired language, create a language file in the `site/languages` folder. The language file should contain the following information:

```
# /site/languages/en.php
return [
    'code' => 'en',
    'default' => true,
    'direction' => 'ltr',
    'locale' => 'en_US',
    // Or if you need multiple locales:
    // 'locale' => [
    //     'LC_ALL' => 'en_US.UTF-8',
    // ]
    'name' => 'English'
];
```

Note

Make sure to set the `locale` option to the correct locale for each language. This is important for the mapping between Kirby and Lingohub.

### 2️⃣ Lingohub Setup

[](#2️⃣-lingohub-setup)

First, create a new project in your Lingohub workspace. Use the file format **JSON (Standard)**:

[![Lingohub platform format](./.github/lingohub-platform-format.png)](./.github/lingohub-platform-format.png)

Now, configure the project to use the same source and target languages as you have in Kirby. The language code in Lingohub should match the locale in Kirby. From the example above, the locale in Kirby is `en_US`. Set the language code in Lingohub to `en-US`. (Note the difference in the delimiter.)

As another example: If the Kirby language code is `de` and the locale is `de_DE`, the Lingohub language code should be `de-DE`.

Finally, create an API key for your workspace. Follow the [Lingohub API key guide](https://help.lingohub.com/en/articles/6775959-how-to-create-an-api-key) to create an API key with read/write access.

Note

Enable full permissions for the **Resources** section in the API key settings. This is required to upload and download translations. No other permissions are needed.

### 3️⃣ Kirby Plugin Configuration

[](#3️⃣-kirby-plugin-configuration)

After setting up the languages in Kirby and Lingohub, configure the plugin in the `site/config/config.php` file.

- To retrieve the workspace ID, open the Lingohub dashboard and copy the workspace ID from the URL. If the URL contains `workspace/space_16kPs3bRIpXi-29323/dashboard`, the workspace ID is `space_16kPs3bRIpXi-29323`.
- For the project ID, open the project in Lingohub and copy the project ID from the URL. If the URL contains `project/pr_18JCETCbT9NW-31003/branches`, the project ID is `pr_18JCETCbT9NW-31003`.

```
# /site/config/config.php
return [
    'languages' => true,

    'johannschopplich.lingohub' => [
        'apiKey' => '',
        'workspaceId' => 'space_123-456',
        'projectId' => 'pr_123-456',
    ]
];
```

### 4️⃣ Blueprint Configuration

[](#4️⃣-blueprint-configuration)

Kirby 5 introduces new extensions that allow you to add custom view buttons to most Panel views (e.g. page, site, or file). The Lingohub plugin provides a dropdown button that can be added alongside the default buttons, such as the languages dropdown button.

To add the `lingohub` dropdown button to a particular view, set the `buttons` option in the corresponding blueprint. The following example shows how to reference the default buttons and add the `lingohub` button to a page blueprint:

```
title: Note

buttons:
  - preview
  - settings
  # Add the Lingohub button to the page view
  - lingohub
  - languages
  - status
```

Note

Kirby 4 does not support custom view buttons, but the `lingohub` button has been backported. It is always placed before the language dropdown.

Finalize your blueprints by adding the necessary translation configuration to each field, e.g. `translate: false` if a field should not be translated. The plugin will skip these fields when uploading content to Lingohub.

Usage
-----

[](#usage)

### Translation Status

[](#translation-status)

The [translation status](https://help.lingohub.com/en/articles/6683154-manage-localization-with-statuses) is automatically retrieved from Lingohub and displayed in the user interface. It reflects the minimum status across all segments of the page. Only when all segments have the **Approved** status will the translation be shown as **Approved** in green:

[![Kirby Lingohub status approved](./.github/kirby-lingohub-status-approved.png)](./.github/kirby-lingohub-status-approved.png)

Click on the status to open a dialog with more detailed information:

[![Kirby Lingohub status dialog](./.github/kirby-lingohub-status-dialog.png)](./.github/kirby-lingohub-status-dialog.png)

### Upload Translations for a Page or File

[](#upload-translations-for-a-page-or-file)

Click on the **Lingohub** dropdown button in the Panel header and select **Upload**.

[![Kirby Lingohub upload translations](./.github/kirby-lingohub-upload.png)](./.github/kirby-lingohub-upload.png)

When you click on the button, a dialog will open where you can select the content you want to upload to Lingohub:

- **Source Language**: Select it to upload the default language content to Lingohub. Pre-selected by default.
- **Target Languages**: All languages that have translations for the current page. Pre-selected if there are no translations in Lingohub. This helps you to identify which languages need to be uploaded for the first time, e.g. when migrating an existing Kirby project to Lingohub.

Note

If no translations are available in Kirby, the **Target Languages** list will be empty.

After selecting the desired languages and confirming the dialog, the plugin will serialize the content and upload it to Lingohub for translation.

### Download Translations from Lingohub

[](#download-translations-from-lingohub)

Click on the **Lingohub** dropdown button in the Panel header and select **Download Translations**. This will open a dialog where you can select the languages and status of the translations to download:

[![Kirby Lingohub download translations](./.github/kirby-lingohub-download.png)](./.github/kirby-lingohub-download.png)

The dialog contains the following fields:

- **Status**: Define the minimum status of the segments to download. The default is **Approved**.
- **Languages**: Select the languages to download. By default, all languages with a status of 100% approved in Lingohub are preselected.

Submit the form to download the translations. The page will be updated with the new translations.

Features
--------

[](#features)

### `translateExternalOnly` Blueprint Field Option

[](#translateexternalonly-blueprint-field-option)

The `translateExternalOnly` option allows you to mark fields that should only be translatable using the external translation service (i.e. Lingohub). For these fields, only the source language is editable. In translations, these fields cannot be edited. Admins can always edit the fields, independent of this setting. Use this for fields where translations should be managed exclusively through Lingohub, ensuring the translation memory stays consistent.

```
fields:
  text:
    label: Text
    type: blocks
    translateExternalOnly: true
```

### `translateInKirbyOnly` Blueprint Field Option

[](#translateinkirbyonly-blueprint-field-option)

The `translateInKirbyOnly` option marks fields that should only be translated within Kirby, not through Lingohub. These fields are excluded from uploads and preserved during downloads – their target language values are never overwritten by Lingohub translations.

This is useful for fields like images or files that differ per language but are managed directly in the Panel.

```
fields:
  image:
    label: Image
    type: files
    translateInKirbyOnly: true
```

Important

The `translateInKirbyOnly` option must be set on individual **field** definitions, not on block fieldset definitions. Kirby only preserves known properties on fieldsets – custom attributes at the block root level are silently discarded.

### Translation Status Table Section

[](#translation-status-table-section)

[![Kirby Lingohub status section](./.github/kirby-lingohub-status-section.png)](./.github/kirby-lingohub-status-section.png)

The status section is similar to [Lingohub's statuses overview](https://help.lingohub.com/en/articles/6788499-words-and-segments-overview) and displays the translation status for all available languages. The status section is read-only and cannot be edited.

To add the status section to a blueprint, use the following configuration:

```
sections:
  lingohubStatus:
    type: lingohub-status
```

FAQ
---

[](#faq)

### How Is Kirby Content Data Mapped to Lingohub?

[](#how-is-kirby-content-data-mapped-to-lingohub)

With the JSON (Standard) file format, Lingohub requires a key-value hierarchy structure where all elements in the chain have a long-term consistent key. Thus, nested data structures like `blocks`, `layout`, `structure`, and `object` fields in Kirby must be flattened to a key-value map. For example, block fields are transformed into a key-value map where the key is generated from the field name, block ID, block type, and content field name: `{fieldName}_{blockId}_{blockType}_{contentFieldName}`. Nested blocks (blocks within custom blocks) produce deeper key chains following the same pattern.

Lingohub uses a path-based approach to identify the content. The path is generated from the Kirby model ID (which doesn't contain any draft status or sort numbers) and the language code.

While Kirby uses a language code as file suffix (e.g., `en`), Lingohub uses a locale code (e.g., `en-US`). The plugin maps the Kirby language code to the Lingohub locale code.

Roadmap
-------

[](#roadmap)

### Media Files

[](#media-files)

- Translate all media files (images, videos, etc.) associated with the page. This is a nice-to-have feature that may be implemented in the future.

### Mass Operations

[](#mass-operations)

- Upload all pages to Lingohub in bulk, including translations if they already exist.
- Download all pages from Lingohub in bulk. Configure which pages to process using a filter: e.g. only pages with a certain status or language.
- Iterate through all pages in Kirby and check if new translations are available in Lingohub. If so, download them.

License
-------

[](#license)

[MIT](./LICENSE) License © 2025-PRESENT [Johann Schopplich](https://github.com/johannschopplich)

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance81

Actively maintained with recent releases

Popularity14

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity47

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 98.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~23 days

Recently: every ~66 days

Total

19

Last Release

113d ago

Major Versions

0.4.0 → 1.0.02025-02-20

### Community

Maintainers

![](https://www.gravatar.com/avatar/b9be5bf8dd3a36f63c00f92a115f1109567745fb3b068617341ffc8a90755d6c?d=identicon)[johannschopplich](/maintainers/johannschopplich)

---

Top Contributors

[![johannschopplich](https://avatars.githubusercontent.com/u/27850750?v=4)](https://github.com/johannschopplich "johannschopplich (93 commits)")[![zwadl](https://avatars.githubusercontent.com/u/4161085?v=4)](https://github.com/zwadl "zwadl (1 commits)")

---

Tags

kirby-cmskirby4kirby5lingohubtranslationsservicekirbylingohub

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/johannschopplich-kirby-lingohub/health.svg)

```
[![Health](https://phpackages.com/badges/johannschopplich-kirby-lingohub/health.svg)](https://phpackages.com/packages/johannschopplich-kirby-lingohub)
```

###  Alternatives

[getkirby/cms

The Kirby core

1.5k584.8k474](/packages/getkirby-cms)[johannschopplich/kirby-content-translator

DeepL &amp; AI-powered content translation for Kirby CMS

2010.8k](/packages/johannschopplich-kirby-content-translator)[gettext/languages

gettext languages with plural rules

7832.7M12](/packages/gettext-languages)[outl1ne/nova-translations-loader

This Laravel Nova package helps developers load translations into their packages.

396.0M55](/packages/outl1ne-nova-translations-loader)[medienbaecker/kirby-modules

Easily add modules to your pages

895.5k1](/packages/medienbaecker-kirby-modules)[laravel-lang/locales

Basic functionality for working with localizations

135.8M20](/packages/laravel-lang-locales)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
