Reputation: 980
I am working on a simple NextJS app, but I am having trouble with component level styling using SASS/SCSS. Everything looks fine when the user first lands on the page, but when the user navigates to a page /about
for example or from /about
to /
, the component styles didn't get render, the user needs to refresh the page to see the styles 🤔
⚙️ SETTINGS
./package.json
"dependencies": {
"@zeit/next-css": "1.0.1",
"@zeit/next-sass": "1.0.1",
"autoprefixer": "^9.7.0",
"next": "^9.3.1",
"node-sass": "4.13.1",
"react": "^16.13.0",
"react-dom": "^16.13.0",
"webpack": "^4.42.0"
}
./next.config.js
const webpack = require('webpack');
const withSass = require('@zeit/next-sass');
const withCss = require('@zeit/next-css');
module.exports = withCss(
withSass({
webpack(config) {
config.module.rules.push({
test: /\.(eot|woff?2|ttf|otf|svg|png|jpe?g|gif)$/,
use: {
loader: 'url-loader',
options: {
limit: 100000,
},
},
});
return config;
},
}),
);
./postcss.config.js
const autoprefixer = require('autoprefixer');
module.exports = {
plugins: [autoprefixer],
};
📄 PAGES
./pages/index.js
import React from 'react';
import Layout from '../components/Layout';
import Home from '../components/Home';
class Index extends React.PureComponent {
render() {
<Layout>
<Home />
</Layout>
}
}
export default Index;
./pages/about.js
import React from 'react';
import Layout from '../components/Layout';
import Company from '../components/Company';
class About extends React.PureComponent {
render() {
<Layout>
<Company />
</Layout>
}
}
export default About;
📦 COMPONENTS
./components/Layout.js
import React from 'react';
import AppBar from '../AppBar/AppBar';
import './Layout.scss';
class Layout extends React.PureComponent {
render() {
const { children } = this.props;
return (
<>
<AppBar />
<main className="Layout">
{children}
</main>
</>
);
}
}
export default Layout;
./components/Layout.scss
.Layout {
background: #f00;
}
./components/AppBar.js
import Link from 'next/link';
import './AppBar.scss';
export default () => (
<header className="AppBar">
<Link href="/">
<a>Home</a>
</Link>
<Link href="/about">
<a>About</a>
</Link>
</header>
)
./components/AppBar.scss
.AppBar {
background: #0f0;
}
./components/Home.js
import './Home.scss';
export default () => (
<div className="Home">Home</div>
)
./components/Home.scss
.Home {
background: #00f;
}
./components/Company.js
import './Company.scss';
export default () => (
<div className="Company">Company</div>
)
./components/Company.scss
.Company {
background: #ff0;
}
Upvotes: 4
Views: 6956
Reputation: 15836
For anyone who is looking for a working answer after nextjs 11. You can refer to this repo, or read full details in this article
Here is full next config code that I have used
const withTM = require('next-transpile-modules')([]);
const withPlugins = require('next-compose-plugins');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = withPlugins([withTM], {
reactStrictMode: true,
webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
// Find and remove NextJS css rules.
const cssRulesIdx = config.module.rules.findIndex((r) => r.oneOf);
if (cssRulesIdx === -1) {
throw new Error('Could not find NextJS CSS rule to overwrite.');
}
config.module.rules.splice(cssRulesIdx, 1);
// Add a simpler rule for global css anywhere.
config.plugins.push(
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: 'static/chunks/pages/[contenthash].css',
chunkFilename: 'static/chunks/pages/[contenthash].css',
}),
);
config.module.rules.push({
test: /\.(sa|sc|c)ss$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
});
config.module.rules.push({
test: /\.tsx/,
use: [defaultLoaders.babel],
});
return config;
},
});
Upvotes: 0
Reputation: 980
This is how I fix my issue. 🎉
With the release of Next.js 9.3, there is no need for @zeit/next-sass
& @zeit/next-css
. 👏
I also do the following:
styled-jsx-plugin-sass node-sassa
as dev-dep.babelrc
file and add the following:{
"presets": [
[
"next/babel",
{
"styled-jsx": {
"plugins": ["styled-jsx-plugin-sass"]
}
}
]
]
}
So I have two options to do it:
<style jsx>
<ComponentName>.module.scss
The second option is a pain in the A, you need to import styles from './ComponentName.module.scss
and add element class as className={styles.ComponentName}
or className={styles['ComponentName-button']}
. 🧐
Upvotes: 3