Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic routing with getServerSideProps in Nextjs

I'm trying to learn nextjs. Struggling to work out routing with getServerSideProps.

Using a free API I have a list of countries displayed on the DOM. I want to dynamically link to a country and data be fetched and displayed for that specific country.

Heres my code so far

const Country = props => (
  <Layout>
    <h1>{props.country.name}</h1>
    <span>{props.country.capital}</span>
  </Layout>
);
export async function getServerSideProps(context) {
  const { id } = context.query;
  const res = await fetch(`https://restcountries.eu/rest/v2/name/${id}`);
  const country = await res.json();

  console.log(`Fetched place: ${country.name}`);
  return { props: { country } };
}
export default Country;

  <div className='container'>
    <Head>
      <title>Countries List</title>
      <link rel='icon' href='/favicon.ico' />
    </Head>
    <Layout>
      <main>
        <h1>
          Countries{' '}
          <span role='img' aria-label='world emoji'>
            🌎
          </span>
        </h1>
        <ul>
          {countries.map(country => (
            <li key={country.name}>
              <Link href='/p/[id]' as={`/p/${country.name}`}>
                <a>{country.name}</a>
              </Link>
            </li>
          ))}
        </ul>
      </main>
    </Layout>
  </div>
);

export async function getServerSideProps() {
  // Call an external API endpoint to get posts.
  const res = await fetch('https://restcountries.eu/rest/v2/all');
  const countries = await res.json();

  // By returning { props: posts }, the Blog component
  // will receive `posts` as a prop at build time
  return {
    props: {
      countries,
    },
  };
}

export default Home;

The URL dynamically routes ok. For example, when you click on Afghanistan the URL shows http://localhost:3000/p/Afghanistan.

My country component however doesn't display anything and undefined is printed to the terminal.

Example of URL and response from URL: https://restcountries.eu/rest/v2/name/Afghanistan

{
name: "Afghanistan"
}

Apologies if a noob question. Trying to learn nextjs

like image 716
DGB Avatar asked Apr 15 '20 06:04

DGB


People also ask

What is getServerSideProps in Nextjs?

getServerSideProps or API Routes An API route is used to fetch some data from a CMS. That API route is then called directly from getServerSideProps . This produces an additional call, reducing performance. Instead, directly import the logic used inside your API Route into getServerSideProps .

Can I use useRouter in getServerSideProps?

useRouter is used for client side routing and can be used at client side and getServerSideProps will be executed at server side. Due to this reason you can't use useRouter() in getServerSideProps.

How can I change URL without reloading page in Nextjs?

Shallow routing allows you to change the URL without running data fetching methods again, that includes getServerSideProps , getStaticProps , and getInitialProps . You'll receive the updated pathname and the query via the router object (added by useRouter or withRouter ), without losing state.

Where can I use getServerSideProps?

If you want to render a page at the time of the request, you can use getServerSideProps to render a page on the server before responding to a request. getServerSideProps will mark the page to be rendered on each request.


1 Answers

export async function getServerSideProps(context) {
  const { id } = context.query;
  const res = await fetch(`https://restcountries.eu/rest/v2/name/${id}`);
  const country = await res.json();

  console.log(`Fetched place: ${country.name}`);
  return { props: { country } };
}

you are returning a nested object from above function

    { props: { country:country } }

so this prop will be attached to props as like this:

      `props.props`

this is how you should implement

const Country = props => (
  <Layout>
    <h1>{props.props.country.name}</h1>
    <span>{props.props.country.capital}</span>
  </Layout>
);

UPDATE

In early version of next.js I think updated after version 9, we were not returning from serverside function by using props. As of now correct way of implementation is

return {
    props: {
      countries,
    },
  };
like image 134
Yilmaz Avatar answered Oct 13 '22 20:10

Yilmaz