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.
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>
</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