Server Side Rendering attempts to convert as much of your webpage as possible to static HTML before serving the site. This means things like making an API call, instead of happening on the client when you navigate to the page, it will happen on the server, before the page is served.


In Next.js, any page that also exports a getServerSideProps function will have that function called when a request is made for that page. You can then return props in that function, which are then passed to the page.

Why Use SSR?

SSR lets you serve up static HTML, rather than using JavaScript at the client to create your page. The benefits of this are:

  • Your page will load faster, as the bundle size is smaller, and you’ve already fetched whatever data you need for it. This is especially helpful for people on slower connections
  • It makes it easier for search engines like Google to more easily index and crawl your site, since it’s just static HTML.
  • You can use server-side code in your app since the code won’t be in the client.

getServerSideProps

Here’s an example that uses a random facts API to retrieve a random fact on request. Just for fun, let’s also use query string parameters to control how many facts we fetch. I’ve also thrown in a use of the os module, which fetches my username from my computer. This is only possible as the code is being ran on the server.

Here’s a simple fetch function using axios. You can ignore the contents of this, the important part is we get out just a simple JSON object containing our facts. If you’d like to read more about axios, check out this article we have here.

function fetchFact() {
    //Just a simple get request which gets back a fact in a JSON object
    return axios
        .get('https://uselessfacts.jsph.pl//random.json?language=en')
        .then((res) => {
            return res.data;
        });
}

Then we have our page component. This just displays our props, with a bit of fancy styling from TailwindCSS.

export default function SSRExample({ name, facts }) {
    console.log('Hi from the client!');
    return (
        <div className="flex h-screen w-screen flex-col items-center justify-center bg-white text-3xl text-white">
            <p className="mb-10 rounded bg-neutral-800 p-10">
                Heres some fun facts from {name}
            </p>
            <ul className="flex max-w-2xl flex-col gap-5 rounded bg-neutral-800 p-10 shadow">
                {facts.map(({ id, text }) => (
                    <li key={id}>{text}</li>
                ))}
            </ul>
        </div>
    );
}

And here’s our getServerSideProps to fetch the data:

export async function getServerSideProps({ query }) {
    const { count } = query;
    const promises = [...new Array(Number(count))].map(() => fetchFact());

    const facts = await Promise.all(promises);
    const name = os.userInfo().username;
    //console.log(facts);
    console.log('Hi from the server!');
    console.log('Count:', count);
    console.log('Username:', name);
    console.log('Facts:', facts);
    return {
        props: {
            name,
            facts,
        },
    };
}

And this is what it looks like!

If we check our consoles, getServerSideProps only runs on the server, so we see the logs from that, but not the one in our component. On the client we get the reverse, the code gets stripped out, and we only see the log from our component.

Dev Server Console
Chrome Dev Tools Console

Hopefully that was a quick introduction to SSR in Next.js. Next.js also supports another kind of pre-rendering, using Static Site Generation, and you can check out more about that here. Let me know in the comments below if you liked this article, if I helped solve your issue, or if you’re having any troubles!

Avatar photo
👋 Hey, I'm Omari Thompson-Edwards
Hey, I'm Omari! I'm a full-stack developer from the UK. I'm currently looking for graduate and freelance software engineering roles, so if you liked this article, reach out on Twitter at @marile0n

💬 Leave a comment

Your email address will not be published. Required fields are marked *

We will never share your email with anyone else.