Routing to "/about" in multi-lang

Hiya,

I am customizing for the “Next.js i18n blog” repository.

I am trying to add “about” page in two language version. I might be lack of the knowledge about front-end and nexjs directory architecture.

Would you please provide me with some advice to add what about.js file looks like into which directory? How should I make “about” link routing to the “about” page ?

Temporally, I just add the link tag into “language-bar.js” but I am not sure if this is appropriate and how to route it to about page.

Hello @JJ

Can you show me a screenshot of your about.js file?

Thank you

Hi,

I do not start to write about.js file yet, so it is just an empty file. I just allocate this empty file under pages directory with my guess.

I was planning to write graphql and extract just simple profile description from dato in two lang but I was not sure if this was good approach or not.
I am looking for any sample code about profile or sample directory. I am also looking for the easiest way to implement “about” page on this blog with dato.

@JJ

Then that is the problem, you can do the query latter inside the file, but first you have to provide a basic structure for your about.js file, mainly, it needs to export a React component:

As you will see, you will be routed to this file when you click the “About” link, once it exports a React component like on that example.

Thank you,

I could understand how the routing works but I am not sure of the way to write graphql.
I would be appreciated if you could provide me the tips or some advise to write the query based on the schema which is set on the dato console like the below picture. I am also curious of the way to debug the query of graphql and nextjs.

@JJ

You can see an example of how a query is made and how its results are then used inside the component in the [slug].js file
To make your own query for your model, you can follow along our documentation: Content Delivery API - Overview - DatoCMS Docs
There you can see how to query the exact parameters you need, and can also see how to do the filtering, and ordering parameters you may possibly also need.

Thank you for providing me tips.

I wrote about.js[1] by following documents and seeing [slug].js.
But I faced with these error message[2]. If you noticed some, please tell me your certain thoughts or tips to fix it.

[1] about.js:


import { useQuerySubscription } from "react-datocms";

import { request } from "../lib/datocms";

import { useRouter } from "next/router";
import { StructuredText } from "react-datocms";
import {
  SectionContainerFlexTwoCols,
  SectionWrapper,
  ColumnFlexTwoCols,
  TextBox,
} from "../components/sectionStyles";

export async function getStaticProps({ preview, locale }) {
  const formattedLocale = locale.split("-")[0];
  const graphqlRequest = {
    query: `{
        about(locale: ${formattedLocale}) {
          typeName
          seo {
            title
            twitterCard
            description
          }
          structuredBody {
            ...AboutModelStructuredBodyFieldFragment
          }
        }
      }
      
      fragment AboutModelStructuredBodyFieldFragment on AboutModelStructuredBodyField {
        blocks {
          typeName
          title
          image {
            url
          }
          text {
            value
          }
        }
      }
      `,
  };

  return {
    props: {
      subscription: preview
        ? {
            ...graphqlRequest,
            initialData: await request(graphqlRequest),
            token: process.env.NEXT_EXAMPLE_CMS_DATOCMS_API_TOKEN,
            environment: process.env.NEXT_DATOCMS_ENVIRONMENT || null,
          }
        : {
            enabled: false,
            initialData: await request(graphqlRequest),
          },
    },
  };
}

export default function About({ subscription }) {
  const {
    data: { about },
  } = useQuerySubscription(subscription);
  console.log(about);

  const { locale, locales, asPath } = useRouter().locale;

  const body = about.structuredBody;

  console.log(body);
  return (
    <StructuredText
      data={body}
      renderBlock={({ record: { typeName, title, image, text } }) => {
        switch (typeName) {
          case "section image left":
            return (
              <SectionWrapper>
                <SectionContainerFlexTwoCols>
                  <ColumnFlexTwoCols hasImg>
                    <img src={image.url} />
                  </ColumnFlexTwoCols>
                  <ColumnFlexTwoCols>
                    <TextBox as="div">
                      <HeadingMedium>{title}</HeadingMedium>
                      <Paragraph as="div">
                        <StructuredText data={text} />
                      </Paragraph>
                    </TextBox>
                  </ColumnFlexTwoCols>
                </SectionContainerFlexTwoCols>
              </SectionWrapper>
            );
          default:
            return null;
        }
      }}
    />
  );
}

[2] error message:

$ yarn run dev -p 3001
yarn run v1.22.17
warning package.json: No license field
$ next -p 3001
ready - started server on 0.0.0.0:3001, url: http://localhost:3001
info  - Loaded env from /Users/xxxx/blog/.env
info  - Using webpack 5. Reason: Enabled by default https://nextjs.org/docs/messages/webpack5
Browserslist: caniuse-lite is outdated. Please run:
npx browserslist@latest --update-db

Why you should do it regularly:
https://github.com/browserslist/browserslist#browsers-data-updating
event - compiled successfully
event - build page: /
wait  - compiling...
event - compiled successfully
event - build page: /about
wait  - compiling...
event - compiled successfully
{
  typeName: 'test',
  seo: { title: 'about', twitterCard: null, description: 'about' },
  structuredBody: { blocks: [ [Object] ] }
}
{
  blocks: [
    {
      typeName: 'section image left',
      title: 'Michel Jean',
      image: [Object],
      text: [Object]
    }
  ]
}
event - build page: /next/dist/pages/_error
wait  - compiling...
event - compiled successfully
error - RenderError: Don't know how to render a node with type "undefined". Please specify a custom renderRule for it!
    at new RenderError (/Users/xxxx/blog/node_modules/datocms-structured-text-utils/dist/lib/render.js:32:28)
    at transformNode (/Users/xxxx/blog/node_modules/datocms-structured-text-utils/dist/lib/render.js:62:15)
    at Object.render (/Users/xxxx/blog/node_modules/datocms-structured-text-utils/dist/lib/render.js:70:18)
    at Object.render (/Users/xxxx/blog/node_modules/datocms-structured-text-generic-html-renderer/dist/lib/index.js:53:44)
    at StructuredText (/Users/xxxx/blog/node_modules/react-datocms/dist/StructuredText/index.js:42:66)
    at processChild (/Users/xxxx/blog/node_modules/react-dom/cjs/react-dom-server.node.development.js:3353:14)
    at resolve (/Users/xxxx/blog/node_modules/react-dom/cjs/react-dom-server.node.development.js:3270:5)
    at ReactDOMServerRenderer.render (/Users/xxxx/blog/node_modules/react-dom/cjs/react-dom-server.node.development.js:3753:22)
    at ReactDOMServerRenderer.read (/Users/xxxx/blog/node_modules/react-dom/cjs/react-dom-server.node.development.js:3690:29)
    at Object.renderToString (/Users/xxxx/blog/node_modules/react-dom/cjs/react-dom-server.node.development.js:4298:27) {
  node: { blocks: [ [Object] ] },
  page: '/about'
}
{
  typeName: 'test',
  seo: { title: 'about', twitterCard: null, description: 'about' },
  structuredBody: { blocks: [ [Object] ] }
}
{
  blocks: [
    {
      typeName: 'section image left',
      title: 'Michel Jean',
      image: [Object],
      text: [Object]
    }
  ]
}
error - RenderError: Don't know how to render a node with type "undefined". Please specify a custom renderRule for it!
    at new RenderError (/Users/xxxx/blog/node_modules/datocms-structured-text-utils/dist/lib/render.js:32:28)
    at transformNode (/Users/xxxx/blog/node_modules/datocms-structured-text-utils/dist/lib/render.js:62:15)
    at Object.render (/Users/xxxx/blog/node_modules/datocms-structured-text-utils/dist/lib/render.js:70:18)
    at Object.render (/Users/xxxx/blog/node_modules/datocms-structured-text-generic-html-renderer/dist/lib/index.js:53:44)
    at StructuredText (/Users/xxxx/blog/node_modules/react-datocms/dist/StructuredText/index.js:42:66)
    at processChild (/Users/xxxx/blog/node_modules/react-dom/cjs/react-dom-server.node.development.js:3353:14)
    at resolve (/Users/xxxx/blog/node_modules/react-dom/cjs/react-dom-server.node.development.js:3270:5)
    at ReactDOMServerRenderer.render (/Users/xxxx/blog/node_modules/react-dom/cjs/react-dom-server.node.development.js:3753:22)
    at ReactDOMServerRenderer.read (/Users/xxxx/blog/node_modules/react-dom/cjs/react-dom-server.node.development.js:3690:29)
    at Object.renderToString (/Users/xxxx/blog/node_modules/react-dom/cjs/react-dom-server.node.development.js:4298:27) {
  node: { blocks: [ [Object] ] },
  page: '/about'
}

Hello @JJ

The problem comes from the fact that you can only use the direct values from a “Structured Text” field as a value for the data parameter of the <StructuredText> element. What you are passing is not the value of a single Structured Text field.

So, let’s say you have a model called Structured Model with a structured text field called structuredText, you would query its value as such:

Then, the response would be along this format:

And this is the value that the <StructuredText> element expects for rendering.

You can read a bit more about this here: Structured Text fields — DatoCMS

1 Like