Working on modern Javascript framework is amazing but there are a couple problems related to rendering all the content on the client-side like:
1- The page takes longer to fully load because all the JS must load, and your application needs to run to determine what to show on the page.
2- Search engines are getting better at running and indexing JavaScript apps, but it’s much better if we can send them content instead of letting them figure it out.
The solution to both of those problems is server rendering. and that is using a React Framework called NextJS. It provides a common structure that allows you to easily build a frontend React application, and transparently handles server-side rendering for you.
Main features provided by Next.js:
- Next.js reloads the page when it detects any change saved to disk.
- Automatic Routing – put in the
pages
folder, and you don’t need any configuration - You can render React components on the server side, before sending the HTML to the client.
- Instead of generating one single JavaScript file containing all the app code, the app is broken up automatically by Next.js in several different resources.Loading a page only loads the JavaScript necessary for that particular page.
- The
Link
component, used to link together different pages, supports aprefetch
prop which automatically prefetches page resources (including code missing due to code splitting) in the background. - You can import JavaScript modules and React Components dynamically.
- Using the
next export
command,to export a fully static site from your app. - TypeScript support
Installing NextJS
1- Using create-next-app. Make sure that you have the latest version of Node.
npx create-next-app
2.then you can immediately run the sample app by running npm run dev
And here’s the result on http://localhost:3000:

Adding a new page
For example if we wanted to add an About Page, create a new file under pages called about.js then add the code below
const About = () => ( <div> <h1>About</h1> </div> ) export default About
then visit the page http://localhost:3200/about
You can create a pages/about/company page, and that page will show up on the URL http://localhost:3000/about/company.
Dynamic content with the router
A blog is a great use case for this, For example a post titled “Hello World” might have the URL /blog/hello-world
. We create a dynamic URL by creating a dynamic page with the []
syntax. So for the blog, we add a pages/blog/[id].js
file. This file will handle all the dynamic URLs under the /blog/
route, like the ones we mentioned above.
- We import it from
next/router
- and once we have
useRouter
, we instantiate the router object using:
const router = useRouter()
- Once we have this router object, we can extract information from it. In particular we can get the dynamic part of the URL in the
[id].js
file by accessingrouter.query.id
. The dynamic part can also just be a portion of the URL, likepost-[id].js
. - So lets create a file –
pages/blog/[id].js
and add the code
import { useRouter } from 'next/router'
export default () => {
const router = useRouter()
return (
<>
<h1>Blog post</h1>
<p>Post id: {router.query.id}</p>
</>
)
}
Now if you go to http://localhost:3200/blog/post you can see this

We can use this id
parameter to gather the post from a list of posts. From a database, for example. To keep things simple we’ll add a posts.json
file in the project root folder.

Update the code to this:
import { useRouter } from 'next/router' import posts from '../../posts.json' export default () => { const router = useRouter() const post = posts[router.query.id] if (!post) return <p></p> return ( <> <h1>{post.title}</h1> <p>{post.content}</p> </> ) } Then it will display the content from the json file

Then we can add a blog page as well by adding a blog file and the code below:
import Link from 'next/link' import posts from '../posts.json' const Blog = () => ( <div> <h1>Blog</h1> <ul> {Object.entries(posts).map((value, index) => { return ( <li key={index}> <Link href='/blog/[id]' as={'/blog/' + value[0]}> <a>{value[1].title}</a> </Link> </li> ) })} </ul> </div> ) export default Blog
It will look like this

More next/router
package
You can access the Next.js Router directly, provided in the next/router
package, and call its push()
method.
now we can use it’s methods:
push()
allows us to programmatically trigger a URL change
router.push('/login')
prefetch()
allows us to programmatically prefetch a URL, useful when we don’t have a Link
tag which automatically handles prefetching for us
router.prefetch('/login')
Full Code will look like:
import { useRouter } from 'next/router' export default () => { const router = useRouter() useEffect(() => { router.prefetch('/login') }) }
How do we make SSR work for dynamic routes
We must provide the component with props, using a special function called getInitialProps()
which is attached to the component.
Now we are going to rewrite the post to:
import posts from '../../posts.json' const Post = props => { return ( <div> <h1>{props.post.title}</h1> <p>{props.post.content}</p> </div> ) } Post.getInitialProps = ({ query }) => { return { post: posts[query.id] } } export default Post
The getInitialProps
function will be executed on the server side, but also on the client side, when we navigate to a new page using the Link
component as we did.
It’s important to note that getInitialProps
gets, in the context object it receives, in addition to the query
object these other properties:
pathname
: thepath
section of URLasPath
– String of the actual path (including the query) shows in the browser
CSS
Next.js comes with styled-jsx
built-in, because that’s a library built by the same people working on Next.js.
To add CSS to a React component in Next.js we insert it inside a snippet in the JSX, which start with
<style jsx>{`
and ends with
`}</style>
Inside this blocks we write plain CSS. Example:
import Link from 'next/link' const Index = () => ( <div> <h1>Home page</h1> <style jsx>{` h1 { font-size: 3rem; } `}</style> <Link href='/about'> <a>About Us</a> </Link> </div> ) export default Index
Adding a wrapper component
All the pages on your site look more or less the same. There’s a chrome window, a common base layer, and you just want to change what’s inside. To do this:
create a components/Layout.js
component:
export default Page => { return () => ( <div> <nav> <ul>...</ul> </nav> <main> <Page /> </main> </div> ) }
And now you can update the index page to this
import Link from 'next/link' import withLayout from '../pages/components/layout' const Index = () => ( <div> <h1>Home page</h1> <style jsx>{` h1 { font-size: 3rem; } `}</style> <Link href='/about'> <a>About Us</a> </Link> </div> ) export default withLayout(Index)
To avoid unnecessarily complicating our codebase, the alternative approach is to use props:
In Layout.js it will be:
export default props => ( <div> <nav> <ul>....</ul> </nav> <main> {props.content} </main> </div> )
and the pages we will code it like this:
import Layout from '../components/Layout.js'
const Page = () => (
<Layout content={( <p>Here's a page!</p> )} />
)
That’s it for now, stay tune for the Part 2 of this post. and Enjoy coding NextJS!
Thanks for this. Could you also create a post on Angular? When is NextJS to be preferred over Angular?
LikeLike