Server-Side Rendering (SSR) is a technique where HTML pages are generated on the server rather than in the browser. This improves SEO, performance, and initial load times. Next.js, a React framework, has built-in support for SSR, allowing developers to render React components on the server before sending them to the browser.
In this guide, we’ll go through how to set up and use SSR with Next.js.
1. What is Server-Side Rendering (SSR)?
SSR is the process of rendering a client-side JavaScript application on the server. When a user makes a request, the server generates the full HTML page with the data preloaded and sends it to the browser. This is different from Client-Side Rendering (CSR), where the browser has to download JavaScript, render the page, and fetch data after the initial load.
2. Why Use SSR?
- Improved SEO: Since the content is already rendered when it reaches the browser, search engines can crawl it easily.
- Faster Initial Load: The browser receives a fully rendered page, making the time to first meaningful paint faster.
- Better Performance for Slow Devices: Offloading rendering to the server reduces the load on the client device.
3. Setting Up Next.js for SSR
Next.js simplifies SSR by allowing you to define SSR behavior for individual pages. By default, Next.js uses Static Site Generation (SSG) for pages, but you can enable SSR using getServerSideProps.
a) Install Next.js
First, create a Next.js application if you don’t already have one:
- Create a new Next.js project:
npx create-next-app@latest my-next-app cd my-next-app
- Start the development server:
npm run dev
This should start the Next.js application onhttp://localhost:3000
.
b) Enabling SSR with getServerSideProps
To enable SSR in Next.js, you use the getServerSideProps
function inside your page components. This function runs on the server every time a request is made for the page.
Here’s how you can create a page with SSR:
- Create a new page (e.g.,
pages/ssr.js
). - Add SSR logic using
getServerSideProps
:// pages/ssr.js export async function getServerSideProps() { // Fetch data from an API or database const res = await fetch('https://api.example.com/data'); const data = await res.json(); // Return the data as props to the page component return { props: { data }, // Will be passed to the page component as props }; } const SSRPage = ({ data }) => { return ( <div> <h1>Server-Side Rendered Page</h1> <pre>{JSON.stringify(data, null, 2)}</pre> </div> ); }; export default SSRPage;
In this example:
getServerSideProps
fetches data from an API and passes it as props to the page component.- Every time this page is requested,
getServerSideProps
is run on the server, fetching fresh data.
c) How getServerSideProps
Works
- The
getServerSideProps
function runs on every request to the page. - It runs on the server, not the client, so you can securely fetch data (e.g., from databases, APIs) and return it.
- The data is serialized and sent to the client as part of the HTML response, so when the page is loaded, it’s already populated with the necessary content.
d) SSR Example with Dynamic Data
Let’s say we want to fetch a list of blog posts from an API and render them server-side.
// pages/blog.js
export async function getServerSideProps() {
const res = await fetch('https://jsonplaceholder.typicode.com/posts');
const posts = await res.json();
return {
props: { posts },
};
}
const BlogPage = ({ posts }) => {
return (
<div>
<h1>Blog Posts (SSR)</h1>
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
);
};
export default BlogPage;
In this case, the blog posts are fetched on the server-side, and the page will be pre-rendered with the posts when it reaches the browser.
4. Performance Considerations for SSR in Next.js
While SSR can improve SEO and initial load times, it’s important to keep performance in mind:
- Data Fetching Latency: Since data fetching happens on the server for each request, it’s essential to optimize the API calls and database queries to ensure fast responses.
- Caching: To avoid hitting the server on every request, consider caching the results. For example, you can cache API data in memory or use tools like Vercel Edge Functions or Redis for caching.
- Server Load: SSR puts more load on the server, as the page needs to be generated on every request. It’s essential to scale your backend appropriately.
5. When to Use SSR in Next.js
- Dynamic Data: Use SSR when your page content changes frequently, and you need to fetch fresh data every time the user visits the page (e.g., dashboards, user-specific content, or news).
- SEO Benefits: When SEO is critical, SSR is an excellent choice because search engine crawlers can easily index content that is pre-rendered and available in the HTML.
- Initial Page Load: If the first meaningful paint time is crucial, SSR can help by serving a fully-rendered HTML page to the browser.
6. Deploying SSR with Next.js
Once your SSR-enabled Next.js app is ready, you can deploy it to Vercel, which is the platform created by the same team behind Next.js, or any other platform that supports Node.js applications.
- Deploying on Vercel:
- You can deploy your Next.js app to Vercel directly by connecting your GitHub repository to Vercel.
- Vercel will automatically detect your Next.js app and deploy it with SSR support out of the box.
- Deploying on Other Platforms:
- Next.js apps with SSR can be deployed to AWS, Heroku, DigitalOcean, or other cloud platforms by setting up a Node.js server.
- Ensure that your server can handle SSR, and consider using a serverless solution for scalability.