#[...slug].astro for a multi-lang page.

71 messages · Page 1 of 1 (latest)

still ore
#

[...slug].astro for a multi-lang page.

still ore
#

I'm going to die in this process

manic cape
#

where are you stuck?

I see a potential problem with the folder structure in src/content. The top level folders should be the names of your collections, in this case src/content/docs

#

is config.ts in the src/content folder? here it looks like it's in src/content/docs

#

ah, ok good. so where specifically are you stuck?

still ore
#

i'm trying to make the slug to set the domain with domain/<lang>/path

#

but I can't

#

using content folder like at official docs

manic cape
#

so you mean visiting /en/my-document for example doesn't work?

still ore
#

yep, or just like go /en/projects doesn't load anything, it throws 404 page

manic cape
#

hmm ok. if you run npm run build what pages does it show being generated?

still ore
#

the index.astro because I started again, but it was refreshing all time

manic cape
#

what do you mean refreshing?

still ore
#

like loading every time

manic cape
#

yeah, try doing a build instead of running the dev server. all page routes will be built so we'll know a little more about what is being generated

#

the console should output a list of all generated routes

still ore
#

I mean, all pages should be at [lang] folder now no?

manic cape
#

yeah, as long as they export a getStaticPaths function

#

which returns all the possible values of lang

still ore
#

okey so now at the index.astro what I set? I mean how do I set the same thing I got at the initial one but with domain/<lang>/?

#

sorry for my english

manic cape
#

Each file under src/pages/[lang]/* needs to export a getStaticPaths function that returns each language to be generated.
For example:

---
export function getStaticPaths () {
 return [
    { params: { lang: 'en' } },
    { params: { lang: 'fr' } },
  ];
}

const { version } = Astro.params;
---
...
still ore
#

i'm logging the getStaticPaths() and got:

[ { params: { lang: 'es' } }, { params: { lang: 'en' } } ]
manic cape
#

in index.astro? so that one is working fine. what about [...slug].astro?

still ore
#

thats from index.astro

#

let me see sir

#

i gettting an error

#

'docs' is not defined

manic cape
#

what file is that coming from?

still ore
#

what file exactly? The error is at the slug

manic cape
#

the file that says 'docs' is not defined. or paste the error here

still ore
#

[...slug].astro file:

---
import { getCollection } from 'astro:content'

const docs = await getCollection('docs')

export async function getStaticPaths() {
  const pages = docs.map((page) => {
    const [lang, ...slug] = page.slug.split('/');
    return { params: { lang, slug: slug.join('/') || undefined }, props: page }
  })
  
  return pages
}

console.log(getStaticPaths())

const page = Astro.props;
const { Content } = await page.render();
---

<Content/>

Error: docs is not defined => [lang]/[...slug].astro:12:3

manic cape
#

ah, ok. so, because of the way getStaticPaths works. anything you do needs to be in getStaticPaths. So you need to create docs in getStaticPaths, like this:

---
import { getCollection } from 'astro:content'

export async function getStaticPaths() {
  const docs = await getCollection('docs')
  const pages = docs.map((page) => {
    const [lang, ...slug] = page.slug.split('/');
    return { params: { lang, slug: slug.join('/') || undefined }, props: page }
  })
  
  return pages
}

console.log(getStaticPaths())

const page = Astro.props;
const { Content } = await page.render();
---

<Content/>
still ore
#

now it works, but now, how do I redirect for all pages using a language?

manic cape
#

do you mean redirect from all /my-page to /[lang]/my-page?

still ore
#

yeah

#

I also should make translations

manic cape
#

You can take a look at how the Astro docs do it:
https://github.com/withastro/docs/blob/main/src/pages/[...enRedirectSlug].astro

So, maybe something like this?

---
import { stripLangFromSlug } from '../util/languages';

export async function getStaticPaths() {
        const docs = await getCollection('docs').filter(page => page.slug.startsWith('en'))
    return docs.map((page) => {
        return {
            params: {
                slug: stripLangFromSlug(page.slug),
            },
            props: {
                englishSlug: page.slug,
            },
        };
    });
}
---

<meta http-equiv="refresh" content={`0;url=/${Astro.props.englishSlug}`} />
#

fair warning, I haven't tested this code 😆

still ore
#

Another thing I have to make sure is the slug I get from the page i the <folder>/<filename> so if I want to go into a blog post it will return blog/<filename>

manic cape
#

yeah, that should work fine

still ore
#

list of things I have to change:

  • redirect to a default lang, in this case 'en'
  • Do a translation dictionary and component to change lang
  • Fix [lang]/<page> structure
#

i'll be asking you

manic cape
# still ore

yeah, every page under src/pages/[lang]/* will need a getStaticPaths function to return all the languages

manic cape
still ore
still ore
manic cape
#

why?

still ore
#

to see what the slug gets

#

the problem is that i think on [lang]/ i have to make an index.astro

still ore
#

Error: GetStaticPathsRequired: getStaticPaths() function is required for dynamic routes. Make sure that you export a getStaticPaths function from your dynamic route.

manic cape
#

you need to export a getStaticPaths function on every page you created under src/pages/[lang]/

still ore
#

uff okey

#

I have it I think, but now how can I render the specific path I want?

manic cape
#

specific path for what

manic cape
#

can you share the code from that page?

#

blog.astro

still ore
#

now, that doesn't exist, its a mdx

#

I have this component Posts.astro:

---
import PostCard from './PostCard.astro'
import { getCollection } from 'astro:content'

const blogPosts = await getCollection('docs')
const filteredPosts = blogPosts.filter(post => post.slug.startsWith('en/blog/'))
console.log(filteredPosts)
---

<ul class="flex flex-col gap-10">
  {filteredPosts.map((post) => (
    <li>
      <PostCard {post} />
    </li>
  ))}
</ul>
#

I think I need a Pages/blog folder

#

and do another slug

manic cape
#

and console.log(filteredPosts) returns all the entries?

#

as in first-commit, and the others you don't want?

still ore
#

Done I think!

#

Now I have just to filter the slug I think

#

to enter a post I get: http://localhost:3000/es/es/first-commit