withastro / astro

The web framework for content-driven websites. ⭐️ Star to support our work!
https://astro.build
Other
46.43k stars 2.46k forks source link

Redirects and content collections at the same time give warning or error #7023

Closed teinett closed 1 year ago

teinett commented 1 year ago

What version of astro are you using?

2.4.2

Are you using an SSR adapter? If so, which one?

node

What package manager are you using?

npm

What operating system are you using?

mac

What browser are you using?

all browsers

Describe the Bug

Connected with #6768.

I have Astro website with content collections in different languages.

My file /src/pages/[lang]/[…slug].astro - I use SSG:

---
export const prerender = true;

import type { CollectionEntry } from 'astro:content';
import Layout from '@/layouts/Layout.astro';
import { getLangFromSlug } from '@/i18n/utils';
import { stripLangFromSlug } from '@/i18n/utils';
import { fetchPages } from '@/utils/fetchPages';

export async function getStaticPaths() {
    const allPages = await fetchPages();
    return allPages.map((page) => {
        const lang = getLangFromSlug(page.slug);
        const slug = stripLangFromSlug(page.slug);
        return { params: { lang, slug }, props: page };
    });
}

export type Props = CollectionEntry<'docs'>;
const { data, render } = Astro.props;
const { Content } = await render();
---

<Layout title={data.title} description={data.description} homepage={data.homepage}>
    <Content />
</Layout>

Function getStaticPaths() is obligatory for content collections. So I have it.

Also I have the page for redirect /src/pages/index.astro - so I use SSR:

---
const headers = Astro.request.headers;
const langHeaders = headers.get('accept-language')

if (langHeaders === null || langHeaders === undefined || langHeaders === '') {
    return Astro.redirect('/en/');
} else {
    const lang = langHeaders.split(',')[0].split('-')[0];
    if (lang !== 'es' && lang !== 'ru') {
        return Astro.redirect('/en/');
    } else {
        return Astro.redirect(`/${lang}/`);
    }
}
---

Redirect requires changes in astro.config.mjs:

export default defineConfig({
        …
    adapter: node({
        mode: 'standalone'
    }),
    …
});

I start my development server.

Problem: I receive warning in console:

[getStaticPaths] getStaticPaths() is ignored when "output: server" is set.

OK, I delete function getStaticPaths() in /src/pages/[lang]/[…slug].astro. After that I have another problem: error in console:

 error   `getStaticPaths()` function is required for dynamic routes. Make sure that you `export` a `getStaticPaths` function from your dynamic route.
  Hint:
    See https://docs.astro.build/en/core-concepts/routing/#dynamic-routes for more information on dynamic routes.

    Alternatively, set `output: "server"` in your Astro config file to switch to a non-static server build. This error can also occur if using `export const prerender = true;`.
    See https://docs.astro.build/en/guides/server-side-rendering/ for more information on non-static rendering.
  File:
    /Users/teine/Development/dimasidore.com/src/pages/[lang]/[...slug].astro

I used recipe about i18n and the code of website docs.astro.build (it has i18n too).

What is the correct way to have redirects and content collections at the same time, but without warnings or errors?

Link to Minimal Reproducible Example

https://stackblitz.com/edit/github-dkjujg?file=README.md

Participation

bluwy commented 1 year ago

The [getStaticPaths] getStaticPaths() is ignored when "output: server" is set. error is directing to the src/pages[lang]/index.astro file, not src/pages/[lang]/[…slug].astro. I guess it would be nice if the error message tells which route file is causing the issue.