Blog>
Snippets

Handling CSS in SSR with TanStack Router

Demonstrate handling CSS styling problems in SSR applications by implementing a solution to manage styles when rendering server-side using TanStack Router.
import { ServerStyleSheet } from 'styled-components';
import express from 'express';
import fs from 'fs';
import ReactDOMServer from 'react-dom/server';
import App from './App';
// Import your main server router component if it exists
Firstly, import necessary modules including ServerStyleSheet from styled-components for handling styles server-side, express for the server, fs for file system access, ReactDOMServer for rendering components to static markup, and your main App or router component.
const app = express();
const PORT = process.env.PORT || 3000;
Initialize the express app and define the port on which the server will run.
app.use(express.static('build', { index: false }));
Serve the static files from the 'build' directory without using the index.html as an entry point, allowing React Router to handle routing.
app.get('/*', (req, res) => {
  const sheet = new ServerStyleSheet();
  try {
    const html = ReactDOMServer.renderToString(
      sheet.collectStyles(<App />)
    );
    const styles = sheet.getStyleTags(); // Extracts the styles
    const indexFile = path.resolve('./build/index.html');
    fs.readFile(indexFile, 'utf8', (err, data) => {
      if (err) {
        console.error('Something went wrong:', err);
        return res.status(500).send('Oops, better luck next time!');
      }
      return res.send(
        data.replace('<div id="root"></div>', `<div id="root">${html}</div>`)
          .replace('</head>', `${styles}</head>`) // Inject styles into the head
      );
    });
  } catch (error) {
    console.error(error);
    res.status(500).send('Server error');
  } finally {
    sheet.seal();
  }
});
Handles any incoming requests by rendering the App component to a string and injecting it into the HTML, along with the styles extracted using ServerStyleSheet. This setup ensures that styles are loaded server-side and sent along with the initial HTML payload.
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});
Start the express server on the defined PORT, logging a message to the console once the server is up and running.