Introduction
This tutorial assumes that you already know how to set up a basic react app and webpack.
Setting up Semantic UI and extending/overriding the default themes with your custom styles in a React app can give you a bad day if not done carefully.
On the webpack side, after ExtractTextPlugin
was deprecated and replaced with MiniCssExtractPlugin
, configuring your webpack to recognise your Semantic UI less and fonts can also be a pain if you haven't done that before.
This tutorial can help you get started within a few minutes, it can also work with Fomantic UI Less.
Code for this tutorial can be found on https://github.com/kudakwashegore/custom-semanticui-react
Dependencies
First things first, a basic setup will require installation of the following dependencies (I use npm, yarn can also work).
npm i -D mini-css-extract-plugin semantic-ui-less less@2.7.3 less-loader css-loader url-loader
npm i -S semantic-ui-react
Please note the version of less
used (2.7.3). Later versions will give you endless nightmares.
I also deliberately used url-loader
instead of file-loader
, file-loader
will give you issues when you want to use your favourite Semantic UI <Icon />
.
Folder Structure
Assuming the following project structure, you can always update your code to match your folder structure.
node_modules/
app/
app.js
index.html
my-custom-semantic-theme/
webpack.config.js
package.json
Webpack
Below are some additional webpack configuration that you need to add in your webpack configuration file.
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const path = require('path');
module.exports = {
resolve: {
alias: {
'../../theme.config$': path.join(
__dirname,
'../my-custom-semantic-theme/theme.config',
),
},
},
module: {
rules: [
{
test: /\.less$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
'css-loader',
'less-loader',
],
},
{
test: /\.woff($|\?)|\.woff2($|\?)|\.ttf($|\?)|\.eot($|\?)|\.svg($|\?)/,
use: 'url-loader',
}
],
},
plugins: [
new MiniCssExtractPlugin({
filename: 'styles/[name].[contenthash].css',
}),
],
};
Semantic UI
- Go on https://github.com/Semantic-Org/Semantic-UI-LESS and download the repo into your
my-custom-semantic-theme/
folder. - Rename file
theme.config.example
totheme.config
. - Rename _site folder to site
- Delete other folders and files in your
my-custom-semantic-theme/
folder and remain with
my-custom-semantic-theme/
site/
theme.config
theme.less
- Open
theme.config
and have the last lines match the following
/*******************************
Folders
*******************************/
/* Path to theme packages */
@themesFolder : 'themes';
/* Path to site override folder */
@siteFolder : '../../my-custom-semantic-theme/site';
/*******************************
Import Theme
*******************************/
@import (multiple) "~semantic-ui-less/theme.less";
@fontPath : "../../../themes/@{theme}/assets/fonts";
/* End Config */
App
We are almost ready. Below is an example of a basic app.js using semantic-ui-react
components.
import React from 'react';
import ReactDOM from 'react-dom';
import { Icon, Button, Segment, Label } from 'semantic-ui-react';
import 'semantic-ui-less/semantic.less'; // if you do this once in your entry point file, you don't have to do it again in other files.
ReactDOM.render(
<Segment>
<p>Hello semantic-ui button with icon</p>
<Button as='div' labelPosition='right'>
<Button color='red'>
<Icon name='heart' />
Like
</Button>
<Label as='a' basic color='red' pointing='left'>
2,048
</Label>
</Button>
</Segment>,
document.getElementById('appRoot'),
);
Testing our app
We are now ready to test if semantic-ui-less is correctly setup. Do the npm start
thing.
To check if you can now override the default semantic-ui styles with your own, open /my-custom-semantic-theme/site/elements/button.variables
and add the following line
@backgroundColor: green;
Refresh your app and you should see your button background color changing to brown.
You can download example code on https://github.com/kudakwashegore/custom-semanticui-react
Latest comments (2)
Thank you for this, and you're linked git project. If it helps anyone else I had to set the version of less-loader so it would play nicely:
npm i -D less-loader@5.0.0
Will this same procedure work with Next.js?