Site fields do not load language specific content

Hi,

i am using kirby as headless for a mulitlanguage page with kql.

Currently it is EN and DE.

In the pages everything works fine, but the site only shows DE content even if the site.en.txt file contains the right values:

Any idea?

Thanks in advance.

Do you have any caching in place on the server? Or expire headers?

1 Like

Hi Texnixe,

i checked that. It is not the case, the behavior is still the same. I added the lines in the .htaccess and flushed the opcache. In the pages it works but not in the β€œsite”.

The .htaccess file:

# Kirby .htaccess

php_value opcache.revalidate_freq 0

# Core rewrite rules
<IfModule mod_rewrite.c>

    RewriteEngine on

    # Make sure to set the RewriteBase correctly if you are running
    # the site in a subfolder otherwise links or the entire site will break.
    # RewriteBase /

    # Block files and folders beginning with a dot, such as `.git`, except for
    # the `.well-known` folder, which is used for Let's Encrypt and `security.txt`.
    RewriteRule (^|/)\.(?!well-known\/) index.php [L]

    # Make site links work.
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*) index.php [L]

</IfModule>

# Pass the Authorization header to PHP.
SetEnvIf Authorization "(.+)" HTTP_AUTHORIZATION=$1

# Security
# Remove the `X-Powered-By` response header providing server-side technology information.
<IfModule mod_headers.c>
    Header unset X-Powered-By
    Header always unset X-Powered-By
    Header set Cache-Control "no-cache, private"
</IfModule>

# Compression for better web performance
<IfModule mod_deflate.c>

    # Force compression for mangled `Accept-Encoding` request headers.
    <IfModule mod_setenvif.c>
        <IfModule mod_headers.c>
            SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
            RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
        </IfModule>
    </IfModule>

    # Compress all output labeled with one of the following media types.
    <IfModule mod_filter.c>
        AddOutputFilterByType DEFLATE "application/atom+xml" \
                                      "application/javascript" \
                                      "application/json" \
                                      "application/ld+json" \
                                      "application/manifest+json" \
                                      "application/rdf+xml" \
                                      "application/rss+xml" \
                                      "application/schema+json" \
                                      "application/geo+json" \
                                      "application/wasm" \
                                      "application/x-font-ttf" \
                                      "application/x-javascript" \
                                      "application/x-web-app-manifest+json" \
                                      "application/xhtml+xml" \
                                      "application/xml" \
                                      "font/opentype" \
                                      "font/otf" \
                                      "image/bmp" \
                                      "image/svg+xml" \
                                      "text/cache-manifest" \
                                      "text/calendar" \
                                      "text/css" \
                                      "text/html" \
                                      "text/javascript" \
                                      "text/plain" \
                                      "text/markdown" \
                                      "text/vcard" \
                                      "text/vtt" \
                                      "text/x-component" \
                                      "text/x-cross-domain-policy" \
                                      "text/xml"

    </IfModule>

</IfModule>

The config file

<?php

return [

    'debug' => env('KIRBY_DEBUG', false),

    'yaml' => [
        'handler' => 'symfony'
    ],
    'date' => [
        'handler' => 'intl'
    ],

    'languages' => env('KIRBY_MULTILANG', false),

    'panel' => [
        'install' => env('KIRBY_PANEL_INSTALL', false),
        'slug' => env('KIRBY_PANEL_SLUG', 'panel')
    ],
    'ready' => function() {
        return [
            'email' => [
                'transport' => [
                    'host' => kirby()->site()->emailhost()->value(),
                    'port' => kirby()->site()->emailport()->toInt(),
                    'security' => kirby()->site()->emailsecurity()->toBool(),
                    'auth' => kirby()->site()->emailauth()->toBool(),
                    'username' => kirby()->site()->emailuser()->value(),
                    'password' => kirby()->site()->emailpass()->value(),
                ]
            ]
        ];
    },
    'cache' => [
        'pages' => [
            'active' => env('KIRBY_CACHE', false),
            'ignore' => fn (\Kirby\Cms\Page $page) => $page->kirby()->user() !== null
        ]
    ],

    // Enable basic authentication for the Kirby API
    // Only needed, if you prefer basic auth over bearer tokens
    'api' => [
        'basicAuth' => true
    ],

    // Default to token-based authentication
    'kql' => [
        'auth' => 'bearer'
    ],

    // Kirby headless options
    'headless' => [
        // Enable returning Kirby templates as JSON
        'globalRoutes' => true,

        // Optional API token to use for authentication, also used
        // for for KQL endpoint
        'token' => env('KIRBY_HEADLESS_API_TOKEN'),

        'panel' => [
            // Preview URL for the Panel preview button
            'frontendUrl' => env('KIRBY_HEADLESS_FRONTEND_URL'),
            // Redirect to the Panel if no authorization header is sent,
            // useful for editors visiting the site directly
            'redirect' => false
        ],

        'cors' => [
            'allowOrigin' => env('KIRBY_HEADLESS_ALLOW_ORIGIN', '*'),
            'allowMethods' => env('KIRBY_HEADLESS_ALLOW_METHODS', 'GET, POST, OPTIONS'),
            'allowHeaders' => env('KIRBY_HEADLESS_ALLOW_HEADERS', 'Accept, Content-Type, Authorization, X-Language'),
            'maxAge' => env('KIRBY_HEADLESS_MAX_AGE', '86400')
        ]
    ]

];

and the .env file:

KIRBY_DEBUG=true
KIRBY_PANEL_INSTALL=true
KIRBY_CACHE=false

KIRBY_HEADLESS_API_TOKEN=test
KIRBY_HEADLESS_ALLOW_ORIGIN=*
KIRBY_HEADLESS_FRONTEND_URL=http://localhost:3000/
KIRBY_MULTILANG=true

the request header on the site tab for EN.

GET /api/site/sections/emailsettings HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7
Cache-Control: no-cache
Connection: keep-alive
Cookie: kirby_session=182b0e91467b02669419bd35d0840de059e28d34%2B1714117832.8f674850ec5f9d6ebc6c.bc97f243b4bba1df4357d2f849293bf163faadcd94183ea135d0eabb57c9af84
Host: api.rh-homes.test
Pragma: no-cache
Referer: http://api.rh-homes.test/panel/site?tab=sitesettings&language=en
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36
content-type: application/json
x-csrf: 451ed015bd41057dda1a51e1cabb61e954dc90643f765dc2670e3824030e8f3b
x-language: en

the language file:

<?php

return [
    'code' => 'en',
    'default' => false,
    'direction' => 'ltr',
    'locale' => [
        'LC_ALL' => 'en_US'
    ],
    'name' => 'Englisch',
    'translations' => [
        ....
    ],
    'url' => NULL
];

i added

translate: false

to some fields in the site blueprint an this works also. when i switch the language these fields appear as readonly.

ok, i found the problem by changing the config file, step by step.

if i remove this part everything works fine.
here i add values from the fields to the email settings. what may be wrong with that?

    'ready' => function() {
        return [
            'email' => [
                'transport' => [
                    'host' => kirby()->site()->emailhost()->value(),
                    'port' => kirby()->site()->emailport()->toInt(),
                    'security' => kirby()->site()->emailsecurity()->toBool(),
                    'auth' => kirby()->site()->emailauth()->toBool(),
                    'username' => kirby()->site()->emailuser()->value(),
                    'password' => kirby()->site()->emailpass()->value(),
                ]
            ]
        ];
    },

i changed it to this and afterwards everything appears as it should:

'ready' => function() {
        return [
            'email' => [
                'transport' => [
                    'host' => kirby()->site()->content(kirby()->language())->emailhost()->value(),
                    'port' => kirby()->site()->content(kirby()->language())->emailport()->toInt(),
                    'security' => kirby()->site()->content(kirby()->language())->emailsecurity()->toBool(),
                    'auth' => kirby()->site()->content(kirby()->language())->emailauth()->toBool(),
                    'username' => kirby()->site()->content(kirby()->language())->emailuser()->value(),
                    'password' => kirby()->site()->content(kirby()->language())->emailpass()->value(),
                ]
            ]
        ];
    },