Dynamic pages in Nextjs and prefetching data

  • img
    Safaldas G
  • October 25,2019

folder-structure

Live demo

Create a dynamic route within the pages directory

Nextjs allows us to create dynamic routes like /author/John, /author/Shakeshere etc.. and get that in your component as {name: 'John'} in your components props by just creating a directory inside /pages. Like in the example below, create author/[name].js .The [ ] is important.

folder-structure-dynamic-pages.png

Getting the parameter in the component

Now we can get the value from the component with the help of useRouter from 'next/router'.

import React from "react";
import { useRouter } from 'next/router';

const Author = () => {
  const {query} = useRouter();
	return (
        <div>
           {query.name}
        </div>
  )
}

export default Author;

We can get the name parameter from the query. The query parameters also will be available in the query.

For example: If we navigate to a route /jK?p=1 , then the query object has the following value.

{
  name: "jK",
  p:1
}

Fetching data from the api

Nextjs will trigger the getInitialProps for fetching the data from client as well as server side. This data is passed as props to the react component. Wow that's so cool. Thanks to Nextjs team.

Documentation for getInitialProps.

import fetch from "isomorphic-unfetch";
/*
* @param request
* @param response
* The object that is returned is available as props.
* The return is required.
* @returns any{}
*/
Author.getInitialProps = async ({ query: { name } })=> {
  const res = await fetch(
    "https://quote-garden.herokuapp.com/quotes/author/" + (name || "Byron Pulsifer")
  );
  const data = await res.json();

  return {
    quotes: data.results,
    name
  };
};	

See that getInitialProps is an async function that has two parameters - request and response. In this example we destructured the request to get the name. Here is the important library isomorphic-unfetch , why fetch? Since we are running two environments- client and server, this library will handle our pain.

Getting data in the component

const Author = ({ name, quotes }) => {
  return (
    <div className="author-body">
      <Head>
        <title>{name} - Quotes</title>
      </Head>
      <span id="back-arrow">
        <a href="/">
          {" "}
          <i className="fa fa-arrow-left"></i>&nbsp;
        </a>
      </span>
      <h1 className="author-name">{name}</h1>
      {quotes.map((quote, i) => (
        <section className="quotes" key={i}>
          <div className="bubble">
            <blockquote>{quote.quoteText}</blockquote>
          </div>
        </section>
      ))}
    </div>
  );
};

The components props is the data returned from the getInitial props. So we can again destructure and use it in our jsx. Here is the link to the repo

demo

Hope you enjoyed the article

Subscribe to newsletter
Need more tech news? Tune in to our weekly newsletter to get the latest updates