Thinkmill / keystatic

First class CMS experience, TypeScript API, Markdown & YAML/JSON based, no DB
https://keystatic.com
MIT License
1.12k stars 76 forks source link

can't access /keystatic route with Astro i18n integration and prefixDefaultLocale: true #1077

Open marcob896 opened 4 months ago

marcob896 commented 4 months ago

Hi, I'm setting up keystatic in a localized project where the first segment of my url is the language locale.

my-domain.com/en/...... mydomain.com/es/.....

I'm not able to enter the keystatic panel because the localhost:4321/keystatic is matched by the src/pages/[lang] route.

I actually found the place where this configured and I added the /en prefix to make it work changing directly the file in my node_modules folder.

ui pattern api pattern

injectRoute({
          // @ts-ignore
          entryPoint: '@keystatic/astro/internal/keystatic-astro-page.astro',
          entrypoint: '@keystatic/astro/internal/keystatic-astro-page.astro',
          pattern: '/en/keystatic/[...params]',
          prerender: false
        });
        injectRoute({
          // @ts-ignore
          entryPoint: '@keystatic/astro/internal/keystatic-api.js',
          entrypoint: '@keystatic/astro/internal/keystatic-api.js',
          pattern: '/en/api/keystatic/[...params]',
          prerender: false
        });

is there a way to set this up through normal config? I think it could be a useful feature

simonswiss commented 4 months ago

Hey!

I am not able to reproduce this issue — I can create a new Astro + Keystatic project and have a top-level [lang] dynamic segment, but the /keystatic route will still resolve to the Keystatic Admin UI.

By creating a new Keystatic + Astro project with the cli:

npm create @keystatic@latest

and selecting Astro...

I can then create a [lang] dynamic segment (or even a catch-all [...lang] segment), and the /keystatic route will still load the Keystatic Admin UI properly.

Do you have more details about the specifics of your setup?

marcob896 commented 4 months ago

Hi, I think I spotted the root cause: I use the i18n Astro official integrations with prefixDefaultLocale = true, that's the problem.

This my astro config:

import { defineConfig } from 'astro/config';
import tailwind from '@astrojs/tailwind';
import react from '@astrojs/react';
import vercel from '@astrojs/vercel/serverless';
import markdoc from "@astrojs/markdoc";
import keystatic from '@keystatic/astro'

// https://astro.build/config
export default defineConfig({
  output: 'server',
  adapter: vercel(),
  prefetch: true,
  // trailingSlash: 'always',
  integrations: [tailwind(), react(), markdoc(), keystatic()],
  i18n: {
    defaultLocale: 'en',
    locales: ['en', 'it', 'es', 'fr'],
    routing: {
      prefixDefaultLocale: true
    },
    fallback: {
      it: 'en',
      es: 'en',
      fr: 'en'
    }
  }
});

If i set the prefixDefaultLocale: false keystatic will indeed work, but my website breaks. Can you fix it?

simonswiss commented 4 months ago

I've created an issue where I'll collate the numerous requests around i18n support in Keystatic — this should help justify carving some time to look into a first-party solution.

https://github.com/Thinkmill/keystatic/issues/1080

stefanprobst commented 4 months ago

in astro 4.6, you can use the "manual" i18n routing strategy, and add your own middleware: https://docs.astro.build/en/guides/internationalization/#manual

marcob896 commented 4 months ago

in astro 4.6, you can use the "manual" i18n routing strategy, and add your own middleware: https://docs.astro.build/en/guides/internationalization/#manual

That's great, so many thanks. It seems to work with the following src/middleware.ts:

import { defineMiddleware } from 'astro:middleware';
import { redirectToDefaultLocale } from 'astro:i18n';

export const onRequest = defineMiddleware(async (ctx, next) => {
    if (ctx.url.pathname === '/') {
        return redirectToDefaultLocale(ctx, 302) as Response;
    }
    return next();
});

I can't make it work with the middleware function though, but everything seems to work as of now.