As i have searched through the previous but could not find any relevant / solved issues on this so I ask...
Current stack: React, express/node, Sass, Webpack, Sass.
I have a question specific to the Styling of pages before server sends them to the browser.
Styling is working perfectly in the browser and by I mean when the pages are being navigated via browser router, all the styling works. However, I need to figure out a way to inject custom Sass styles to the page before the Server sends the page to the browser.
Current behavior: I access any page from the browser, I get serve the page with correct styling BUT there is a minor delay to get the correct styling in place to appear on the page. If view in slow motion, page appears without styling (because the server sent the page with no styling) and then browser takes over with correct styling.
I have tried webpack to generate all styles in a separate file but I can't seem to link this file to page before server sends it to the browser.
Any help / feedback will be appreciated?
server.js(route handler)
app.get('*', (req, res) => {
const store = createStore();
const promises = matchRoutes(Routes, req.path).map(({ route }) => {
return route.loadData ? route.loadData(store) : null;
});
Promise.all(promises)
.then(() => {
const context = {};
const content = renderer(req, store, context);
if (context.notFound) res.status(404);
res.send(content);
});
});
const PORT = process.env.PORT || 3000;
renderer.js
import React from 'react';
import { renderToString } from 'react-dom/server';
import { StaticRouter, matchPath } from 'react-router-dom';
import { Provider } from 'react-redux';
import { renderRoutes } from 'react-router-config';
import serialize from 'serialize-javascript';
import Routes from '../client/Routes';
export default (req, store, context) => {
// req.path is the url that the user is trying to access
const content = renderToString(
<Provider store={store}>
<StaticRouter location={req.path} context={context}>
<div>
{ renderRoutes(Routes) }
</div>
</StaticRouter>
</Provider>
);
return `
<html>
<head>
<link rel="stylesheet" href="../../public/styles.css">
</head>
<body>
<div id='app'>${content}</div>
<script>
window.INITIAL_STATE = ${serialize(store.getState())}
</script>
<script src="bundle.js"></script>
</body>
</html>
`;
};
webpack.config.js (I omitted the rest of config since its not relevant)
const extractSass = new ExtractTextPlugin({
filename: "styles.css",
disable: process.env.NODE_ENV === "development"
});
module: {
rules: [{
test: /\.scss$/,
use: extractSass.extract({
use: [{
loader: "css-loader"
}, {
loader: "sass-loader"
}],
// use style-loader in development
fallback: "style-loader"
})
}]
},
plugins: [ extractSass ],
This gives me a styles.css
file in my /build
folder. How can i link this to my html. If i try to throw a <link>
tag the browser does not recognize the file.
Yes! This is where server-side rendering for React comes in. In this article, I want to introduce you to server-side rending (SSR) with React, reasons to use it, and some popular frameworks for rendering React on the server side.
Can I use Sass? If you use the create-react-app in your project, you can easily install and use Sass in your React projects. Now you are ready to include Sass files in your project!
In fact, it was Facebook's release of the React library that popularised a CSR approach to applications by making it more technologically accessible. On the other hand, a web-based app serving mainly static content, like this website, would be expected to opt for an SSR approach.
Next. js is used for server side rendering of react application . React along with other framework like angular and vue. js are traditional client side framework ,they run in browser but there are technology to run this framework on server side, and next.
I finally solved this issue by creating another route handler.
app.get('/styles.css', (req, res) => {
res.sendFile(__dirname + "/" + "styles.css");
});
My webpack compiles a styles.css
file which gets put in the /public
folder. Please note i changed the path of my styles file in webpack to this: ../public/styles.css
app.use(express.static('public'));
Above statement ^^^ makes the styles.css
file accessible and finally styles are applied by supplying the below <link>
tag in the response of server to the browser.
<link rel="stylesheet" href="../../public/styles.css">
If anyone else have a better solution, I would love to get feedback.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With