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
| Criterion | Description |
|---|---|
| Main Technical Topic | Server 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 Steps | 1️⃣ Next.js installation. 2️⃣ Adding global styles. 3️⃣ Experiment with styled-components. 4️⃣ Error observation after SSR. 5️⃣ Permanent solution with styled-jsx. |
| Technical Purpose | To 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 Pattern | Definition | Notes |
|---|---|---|
| Global Styles | External CSS or CDN files are added. | It is generally used for fonts and resets. It may cause component conflicts. |
| Inline Styles | It 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)
- 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.
- Does styled-components support SSR now?
Yes, but requires special _document.js configuration. styled-jsx comes with a ready-made integration.
- Can I define global style with styled-jsx?
Yes, you can use the global key:
<style jsx global>{`body { margin: 0; }`}</style>
- 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.

