Support Online
Skip to main content

Properly Rendering CSS Server Side (SSR) in Next.js Projects

🎯 What Will You Learn in This Guide?

This guide teaches you how to properly render CSS server-side in Next.js-based React applications.
The aim is to eliminate the problem of FOUC (Flash of Unstyled Content), that is, “unstyled content flash”.
You will analyze SSR incompatibilities with styled-components and learn how to establish a permanent style structure with styled-jsx, the built-in solution of Next.js.

🧠 Technical Summary

CriterionDescription
Main Technical TopicServer Side Rendering (SSR) of CSS in Next.js applications.
Which Problem Does It Solve?Fixes loss of component styles, className mismatches, and FOUC errors during SSR.
User Steps1️⃣ Next.js installation. 2️⃣ Adding global styles. 3️⃣ Experiment with styled-components. 4️⃣ Error observation after SSR. 5️⃣ Permanent solution with styled-jsx.
Technical PurposeTo show the page to the user without loss of style by ensuring that CSS is generated during server rendering.

💅 1. Styling Patterns Used in React

There are three common styling methods used in React projects, but each behaves differently in an SSR scenario:

Style PatternDefinitionNotes
Global StylesExternal CSS or CDN files are added.It is generally used for fonts and resets. It may cause component conflicts.
Inline StylesIt is applied directly to the DOM element via the style prop.There is no support for pseudo-class (like:hover).
Component Based (CSS-in-JS)With tools like styled-components or Emotion, CSS is written within the component.It is a reusable, modern method, but SSR compatibility requires additional configuration.

⚙️ 2. Project Setup and Adding Global CSS

First, let's create the Next.js project and add the basic styles.

📦 Installation
mkdir next-ssr-css-ornek
cd next-ssr-css-ornek
npm init -y
npm install next@10.2.3 react@17.0.2 react-dom@17.0.2

Add development script to package.json file:


{
"scripts": {
"dev": "next"
}
}
🌐 First Page and Global CSS

Create the pages/index.js file:


import React from 'react';
import Head from 'next/head';

const Index = () => (
<div>
<Head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/7.0.0/normalize.css" />
<link href="https://fonts.googleapis.com/css?family=Raleway" rel="stylesheet" />
<link rel="stylesheet" href="/static/base.css" />
</Head>
<h1>Merhaba, Next.js Projemiz!</h1>
</div>
);

export default Index;

Create static/base.css:


body {
font-family: 'Raleway', sans-serif;
color: #222;
}

This file defines global styles. Now you can start the project with npm run dev and see the result on localhost:3000.


💥 3. SSR Problem with styled-components

Now let's use the popular CSS-in-JS library styled-components.


npm install styled-components@5.3.0

Create the components/Button.js file:


import React from 'react';
import styled from 'styled-components';

const ButtonBase = (props) => <button {...props}>{props.children}</button>;

const Button = styled(ButtonBase)`
background: #0077e2;
box-shadow: 0 2px 7px rgba(120,137,149,0.25);
border-radius: 3px;
padding: 10px;
color: #fff;
border: #0077e2;
text-transform: uppercase;
`;

export default Button;

And call it in pages/index.js:


import Button from '../components/Button';

const Index = () => (
<div>
<h1>Merhaba, Next.js!</h1>
<Button>Tıkla</Button>
</div>
);
⚠️ Problem: Loss of Style (FOUC)

When you “hard refresh” the page (Ctrl+Shift+R), the button styles are lost. The following error appears in the console:


Warning: Prop `className` did not match.

styled-components renders styles only on the client side, so they are not included in the SSR output.


🧩 4. Permanent Solution with styled-jsx

styled-jsx, included with Next.js, renders styles on both the client and server side. It does not require additional installation.

🧱 Let's Rewrite the Button Component

import React from 'react';

const Button = (props) => (
<button {...props}>
{props.children}
<style jsx>{`
background: #0077e2;
box-shadow: 0 2px 7px rgba(120,137,149,0.25);
border-radius: 3px;
text-transform: uppercase;
padding: 10px;
color: #fff;
border: #0077e2;
`}</style>
</button>
);

export default Button;

In this way, the style is rendered simultaneously in both the SSR stage and the browser.


🧠 5. Styling Multiple Elements

You can use CSS selectors in components with multiple HTML elements:


const TitleAndButton = () => (
<div>
<h1 className="baslik">Başlık</h1>
<button>Tıkla</button>
<style jsx>{`
h1.baslik { color: #222; }
button {
background: #0077e2;
color: white;
padding: 10px;
border-radius: 4px;
}
`}</style>
</div>
);

You no longer experience FOUC when you refresh the page — the styles are loaded from the server.


💬 Frequently Asked Questions (FAQ)

  1. Why is Server Side Rendering of CSS important?

SSR increases initial load speed and provides better SEO for search engines. SSRing styles eliminates the "styleless loading" problem.

  1. Does styled-components support SSR now?

Yes, but requires special _document.js configuration. styled-jsx comes with a ready-made integration.

  1. Can I define global style with styled-jsx?

Yes, you can use the global key:


<style jsx global>{`body { margin: 0; }`}</style>
  1. Which method should I choose?

Choose styled-jsx for component-based styles and global CSS for application-wide.


🏁 Result

In this guide, you learned how to render SSR-compliant CSS in Next.js projects. We have permanently solved the style loss problem experienced with styled-components with styled-jsx.

⚡ By ensuring that your styles are rendered on the server, you can reduce the initial loading time and provide your users with a smooth visual experience.

💡 Test these techniques immediately in your Next.js projects that you started on the GenixNode platform and observe the performance difference.