• If you are still using CentOS 7.9, it's time to convert to Alma 8 with the free centos2alma tool by Plesk or Plesk Migrator. Please let us know your experiences or concerns in this thread:
    CentOS2Alma discussion
  • Please beaware of a breaking change in the REST API on the current Plesk release (18.0.62).
    Starting from Plesk Obsidian 18.0.62, requests to REST API containing the Content-Type header with a media-type directive other than “application/json” will result in the HTTP “415 Unsupported Media Type” client error response code. Read more here

Question Issue with Multilingual SvelteKit Website on Plesk: Nginx Proxy to Apache Configuration

st3v3y

New Pleskian
Server operating system version
Ubuntu 20.04.6 LTS
Plesk version and microupdate number
Plesk Obsidian Web Host Edition 18.0.58 Update #2
Problem Description:

I am running a multilingual website built with SvelteKit on a Plesk-managed server. The site supports English (default), German, and Spanish. When accessed locally (e.g., /de for German, /es for Spanish), the site works perfectly, displaying content in the respective languages. However, when deployed on the production server, accessing /de or /es shows the correct language for a brief moment before redirecting back to the default English content, while the URL in the address bar remains /de or /es. Switching the language on the site works. Here you can see the current state on my website: eg. https://mediakular.com/de

I think that the issue is related to the Apache/Nginx configuration. I have tried various setting combinations (in Apache & nginx Web Server Settings) and tried many additional directives that I found online for both Apache and Nginx, but as I am not an expert in this area I don't find a working solution.

I would be very grateful for any tips or solutions.

Relevant Server Code:

Here is the relevant part of my SvelteKit configuration (hooks.server.ts):

JavaScript:
import { defaultLocale, loadTranslations, locales } from '$lib/translations';
import type { HandleServerError } from '@sveltejs/kit';

const routeRegex = new RegExp(/^\/[^.]*([?#].*)?$/);

/** @type {import('@sveltejs/kit').Handle} */
export const handle = async ({ event, resolve }) => {
    const { url, request, isDataRequest } = event;
    const { pathname, origin } = url;

    // If this request is a route request
    if (routeRegex.test(pathname)) {
        const supportedLocales = locales.get().map((l) => l.toLowerCase());
        let locale = supportedLocales.find((l) => l === `${pathname.match(/[^/]+?(?=\/|$)/)}`.toLowerCase());

        if (locale === defaultLocale && !request.headers.get('prevent-redirect')) {
            const localeRegex = new RegExp(`^/${locale}`);
            const location = `${pathname}`.replace(localeRegex, '') || '/';
            return new Response(undefined, { headers: { location }, status: 301 });
        } else if (!locale) {
            if (!isDataRequest) {
                locale = `${`${request.headers.get('accept-language')}`.match(/[a-zA-Z]+?(?=-|_|,|;)/)}`.toLowerCase();
            }

            if (!supportedLocales.includes(locale ?? "")) {
                locale = defaultLocale;
            }

            if (locale === defaultLocale) {
                const path = `${pathname}`.replace(/\/$/, '');
                const redirectTo = `${origin}/${locale}${path}${isDataRequest ? '/__data.json?x-sveltekit-invalidated=100' : ''}`;
                request.headers.set('prevent-redirect', '1');
                const response = await fetch(redirectTo, request);
                const data = await response.text();

                return new Response(data, {
                    ...response,
                    headers: {
                        ...response.headers,
                        'Content-Type': isDataRequest ? 'application/json' : 'text/html',
                    },
                });
            }

            return new Response(undefined, { headers: { 'location': `/${locale}${pathname}` }, status: 301 });
        }

        return resolve({ ...event, locals: { lang: locale } }, {
            transformPageChunk: ({ html }) => html.replace('%lang%', `${locale}`),
        });
    }

    return resolve(event);
};

/** @type {import('@sveltejs/kit').HandleServerError} */
export const handleError = async ({ event }) : Promise<HandleServerError> => {
    const { locals } = event;
    const { lang } = locals;

    await loadTranslations(lang, 'error');

    return locals as unknown as HandleServerError;
};
 
Last edited by a moderator:
Back
Top