Query specific collection with all locales

default discord avatar
mumincelallast year
10

Hi,



I have multi-language data on the database and I want to get all other slugs of the document based on language. Because when I want to switch language on the website I need to go to page in other language of specific page.



I am using below code structure to get specific page.



export const getServerSideProps: GetServerSideProps = async ({
  params,
  locale,
  defaultLocale
}) => {
  const slug =
    params?.slug && Array.isArray(params.slug) ? params.slug.join('/') : 'home';

  const page = await getPageBySlug<PaginatedDocs<PageType>>({
    slug,
    locale,
    defaultLocale
  });

  return {
    props: {
      page: page.docs[0] || null
    }
  };
};


There is an option

locale=all

but this option only works if I query all documents of the collection. But I need all locale slug data of the specific document.



How can I do this?



@jarrod_not_jared @alessiogr @ncaminata @tylandavis or any payload team member or anyone knows about it.



This is critical for my project right now. Please could you explain this to me if there is any solution?

  • default discord avatar
    tinoutilast year

    Would you mind sharing what your

    getPageBySlug

    function looks like? Are you using the REST API?

  • default discord avatar
    imcorfitzlast year

    I have been able to retrieve all languages when querying my REST API using

    ?locale=all

    however GraphQL doesn't allow for it.

  • default discord avatar
    mumincelallast year

    Yes it is REST API.



    export const getCustomPageDataBySlug = async <T>({
      endpoint,
      slug,
      locale,
      defaultLocale
    }: {
      endpoint: string;
      slug: string;
      locale?: string;
      defaultLocale?: string;
    }) => {
      try {
        const query = await fetch(
          `${BASE_URL}/${endpoint}?locale=${locale}&fallbackLocale=${defaultLocale}&where[slug][equals]=${slug}`
        );
    
        const data: T = await query.json();
    
        return data;
      } catch (error) {
        if (error instanceof Error) {
          throw new Error(JSON.stringify(error));
        }
    
        throw new Error('An error occurred');
      }
    };
    
    export const getPageBySlug = async <T>({
      slug,
      locale,
      defaultLocale
    }: {
      slug: string;
      locale?: string;
      defaultLocale?: string;
    }) =>
      getCustomPageDataBySlug<T>({
        endpoint: 'pages',
        slug,
        locale,
        defaultLocale
      });


    ?locale=all

    works only when you retrieve all pages in a page collection. When you try to all languages of a specific page, then

    ?locale=all

    not working. I mean if I use

    slug

    query with

    ?locale=all

    , empty result comes. Did you use the

    ?locale=all

    query to select all collection data or to select specific data?

  • I believe this PR would allow you to do this in a more "correct" way (

    https://github.com/payloadcms/payload/pull/2796

    ). But, even though eslint will yell at you, this will technically work:



    // ... rest of your config
    hooks: {
      beforeRead: [
        ({ doc }) => {
          doc.localizedSlugs = JSON.stringify(doc.slug);
          return doc;
        },
      ],
    },
    fields: [
      {
        name: 'slug',
        type: 'text',
        localized: true,
        index: true,
      },
      {
        name: 'localizedSlugs',
        type: 'json',
      },
    ],
  • default discord avatar
    imcorfitzlast year

    On a specific record I can get all languages for multiple fields, by passing

    ?locale=all

    in the REST API. However, I don't know if part of a filter/search it is different of course.

    Screenshot_2023-07-25_at_14.55.40.png
  • default discord avatar
    mumincelallast year

    I understand but right now I am using slug instead of ID. I need to change whole structure if I use ID instead of slug.

  • default discord avatar
    imcorfitzlast year

    @jarrod_not_jared seems to have found a smart workaround though.. adding

    {admin: {hidden: true}}

    as well, will make it so you don't have to look at it neither in admin, but the data is still returned by the API.

  • default discord avatar
    mumincelallast year

    This works, thank you @jarrod_not_jared

  • I believe the Context PR was merged! So you could likely use that if you would like 🙂

  • default discord avatar
    mumincelallast year

    I updated payload version and I started to use it. Works like charm. Thank you

Star on GitHub

Star

Chat on Discord

Discord

online

Can't find what you're looking for?

Get help straight from the Payload team with an Enterprise License.