FontAwesome Icons not working properly in react/next app - reactjs

Solved - TLDR; Adding import '#fortawesome/fontawesome-svg-core/styles.css' to the _app.js / index.js file fixes the issue and FontAwesome works as intended. My issue was caused by npx-create-next-app including purgeCSS by default, which in turn stripped out the FontAwesome required styles.
I'm using FontAwesome in my Next app. I followed the React guide on the FA website and the icon SVG's are being output on the page. Problem is, none of the features work and they don't scale with font-size as they're meant to.
I don't want to hack it together by manually targeting the SVG's and adding size etc. as it's not ideal when it comes to responsiveness. i.e. it would be nice to have icons scale with accompanying text and the ability to add 'spinner', 'fixedWidth' etc.
Strangely, they have started working once or twice but then break again and I can't seem to reproduce.
// package.json
"dependencies": {
"#fortawesome/react-fontawesome": "^0.1.14",
"#fortawesome/fontawesome-svg-core": "^1.2.34",
"#fortawesome/pro-regular-svg-icons": "^5.15.2",
}
// _app.js
import { library } from '#fortawesome/fontawesome-svg-core'
import { faHeart } from '#fortawesome/pro-regular-svg-icons'
library.add( faHeart )
// header.js
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome'
export default function Header() {
return (
<header>
<FontAwesomeIcon icon={['far', 'heart']} spin />
</header>
)
}
// style.css
header {
font-size: 20px; (does nothing to the icon)
}
svg {
width: 20px; (works, but this shouldn't be required according to FA docs)
}
I've also tried individual use (importing icons into individual components, rather than utilising the library function) to the same effect. Like so:
// header.js
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome'
import { faHeart } from '#fortawesome/pro-regular-svg-icons'
export default function Header() {
return (
<header>
<FontAwesomeIcon icon={faHeart} spin />
</header>
)
}

Fixed it. The issue was purgeCSS which was added to the project when using npx-create-next-app. purgeCSS was purging the required FontAwesome styles.
Explicitly importing the FontAwesome styles fixed the issue.
Specifically, I added import '#fortawesome/fontawesome-svg-core/styles.css' to _app.js.

According to the doc, The react-fontawesome component integrates well with Next.js but there is one caveat you need to solve. Since Next.js manages CSS differently
In your project entry, probably App.js
import { config } from '#fortawesome/fontawesome-svg-core'
import '#fortawesome/fontawesome-svg-core/styles.css'
config.autoAddCss = false
Next.js allows you to import CSS directly in .js files. It handles optimization and all the necessary Webpack configuration to make this work.
import '#fortawesome/fontawesome-svg-core/styles.css'
You change this configuration value to false so that the Font Awesome core SVG library will not try and insert elements into the of the page. Next.js blocks this from happening anyway so you might as well not even try.
config.autoAddCss = false

I use FontAwesomeIcon in my React apps like this and it works:
import { faHeart} from "#fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
in the code:
<FontAwesomeIcon className="icon" icon={faHeart} />
and in css:
.icon{
color: ; / if you want to change color
font-size: 36px;
}

Essentially, all you need to do is:
import the icon:
import { yourIcon} from "#fortawesome/free-solid-svg-icons";
and use it:
<FontAwesomeIcon icon={yourIcon} />
You can add a classname to the icon and use that class to style it.
<FontAwesomeIcon icon={yourIcon} className="styled-icon" />
Here is a good video on adding font awesome icons to next.js: https://youtu.be/kaA2aX4X3NU

Related

React FontAwesome - problem on loading fa-thin

Trying to use FontAwesome icons on React but I am having some issues on importing the files correctly.
First I installed some dependencies and I am now able to import the component as follow
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome'
import { faTrash } from "#fortawesome/free-solid-svg-icons";
and use it (succesfully) as
<FontAwesomeIcon icon={faTrash} />
However, the icon I would like to use is this one ( icon ) but I can't seem to be able to actually import it. If I try import { faThin } from "#fortawesome/free-solid-svg-icons"; it doesn't work and if I try import { faThin } from "#fortawesome/free-thin-svg-icons"; it doesn't neither.
Any ideas?
That font is part of the light package (fa-light fa-trash), so you will need:
#fortawesome/pro-light-svg-icons
and a subscription to pro.

Font Awesome Icon in Next JS works with single Component/Variation only

I've gotten the icons to import by using the import statements and then utilizing the imported components, however, many of the icons act like classes and if you want variations of the icon you need to add to the class. I cannot do this with pre-defined components and when I define icon = "" in quotes rather than importing a component it does not work.
When I go on the website, for example, it gives me this code for React:
<FontAwesomeIcon icon="fa-solid fa-bold" />
My code:
import { faSolid, faBold } from "#fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
...
//Works
<FontAwesomeIcon icon={faBold} />
//Doesn't work
<FontAwesomeIcon icon="fa-solid fa-bold" />
<FontAwesomeIcon icon={{faBold, faSolid}} />
I should also mention that I followed a small tutorial on from a blog and added this code to my pages/_app.js file:
import "#fortawesome/fontawesome-svg-core/styles.css";
import { config } from "#fortawesome/fontawesome-svg-core";
config.autoAddCss = false;
It depends on how you import the packages. It's recommended for newer users to do what was working:
import { faSolid, faBold } from "#fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
...
//Works
<FontAwesomeIcon icon={faBold} />
//faSolid doesnt exist.
If you REALLY want to do it the other way, and just so you know there are a lot of drawback to it, you would need to import the package globally to your website. Again, I wouldn't recommend it, if you are just learning the package. It's extremelly easy to do individual imports, if you know the name of the icon you want to import then you type
import {faThumbsUp} from '#fortawesome/free-regular-svg-icons'
the trick is when you go to fontawesome you pick your icon then in the upper left hand corner you can pick from which library theres solid, thin, etc. and that is the name of the package.
// regular
#fortawesome/free-regular-svg-icons
// solid
#fortawesome/free-solid-svg-icons
They are all saved the same
faThumbsUp
faAlien
faThumbtack
// etc...

How to override prime-react component CSS styling?

I am using prime-react to style my React page. But I want a more compact website with very few padding and minimum styling. For this purpose, I want to override a few CSS properties for the prime-react components.
For eg, I am trying to reduce the padding for the MenuBar -
HomePage.js
import {React, Component } from 'react';
import { Menubar } from 'primereact/menubar';
import 'primereact/resources/themes/saga-blue/theme.css';
import 'primereact/resources/primereact.min.css';
import 'primeicons/primeicons.css';
import styled from "styled-components";
export default class HomeMenuBar extends Component {
// menu code ...
render() {
return (
<div>
<div className="card">
<Menubar model={this.items} className={this.props.className} />
</div>
</div>
);
}
}
const ComponentView = styled(HomeMenuBar)`
.p-menubar .p-menubar-root-list > .p-menuitem > .p-menuitem-link {
padding: 0.1rem 1rem !important;
}
`;
The above code makes no difference to the original styling.
I am trying to make use of this component.
However, particularly using these styled-components I don't like it. I am new to react and would like to know if there are better alternatives like, storing the CSS properties in another file and then importing it in the required file. I tried this part but it also didn't work out.
I work with react over a year and have seen lot of different ways to customise components and so far, I think that styled-components is the most convenient way to customize components if you cook them right.
I love to put all customized components with styled to a separate file near the index.js called styled.js of Component.js and Componnet.styled.js (in the separate folder of course MyComponent/index.js);
In styled.js you export all components like this:
export const Container = styled.div`
.p-menubar .p-menubar-root-list > .p-menuitem > .p-menuitem-link {
padding: 0.1rem 1rem !important;
}
`
In index.js file you inport them like this:
import {Container} from './styled'
// or import * as Styled from './styled' (if you have a lot of customized components);
export default class HomeMenuBar extends Component {
// menu code ...
render() {
return (
<Container>
<div className="card">
<Menubar model={this.items} className={this.props.className} />
</div>
</Container>
);
}
}
If you want to try something more like classic css try to look at css-modules.
This article can help https://www.triplet.fi/blog/practical-guide-to-react-and-css-modules/
You can also try patch-styles, a more declarative way to apply CSS/SCSS modules to your code. Also, check out the StackBlitz example.

Use antd for React together with Storybook v5

Now, I am stuck for several hours trying to make Storybook work with antd in my new React application (created with create-react-app), without success.
Whatever I do, Storybook does not take the styling of antd.
For example, I created a menu item with antd:
menuNav.tsx:
import React from "react";
import {Menu} from 'antd';
import "antd/dist/antd.less";
const MenuNav = () => {
return (
<Menu mode="horizontal">
<Menu.Item key="menu1">
This is my menu title
</Menu.Item>
</Menu>
)
}
export default MenuNav;
But the result looks like this, no styling at all, but a list:
And as you can see here, it understands that the menu is created by the UI library, but there is no antd styling applied:
This is the story file of MenuNav, 3-Menu.stories.js:
import React from "react";
import MenuNav from '../components/MenuNav';
export default {
title: "MenuNav",
component: MenuNav,
};
export const Text = () => <MenuNav></MenuNav>
I already tried to add a config.js inside ./storybook as suggested here, with no success. Furthermore, I tried adding a webpack.config.js in the same directory as recommended here, same result.
What am I doing wrong?
try adding #import '~antd/dist/antd.css'; to your applications main file, let say index.css which for example is placed in src folder and then add import '../src/index.css'; to .storybook/preview.js
`

Ant design page reloading css rendering delay

I used my react TypeScript project for ant-design, I have some issue when I reload the page, css loading delay, any reason for this?
I imported my main.css to
#import './../node_modules/antd/dist/antd.css';
Actually, based on And Design Doc about getting a start, You could use babel plugin for automatic loading used components like below, it is a recommended way:
// .babelrc or babel-loader option
{
"plugins": [
["import", { "libraryName": "antd", "libraryDirectory": "es", "style": "css" }] // `style: true` for less
]
}
By using this way (from docs):
This allows you to import components from antd without having to manually import the corresponding stylesheet. The antd babel plugin will automatically import stylesheets.
So you can import the component easily and there is no need to load CSS manually, just like below:
import { Button } from 'antd';
But if you don't want to use the above plugin, you can use Ant Desing component by importing its CSS inside each component like below:
import React from 'react';
import Button from 'antd/es/button';
import 'antd/es/button/style/css'; // <<=== this way
import './CustomButton.css';
const CustomButton = () => (
<div className="custom-button">
<Button type="primary">
Button
</Button>
</div>
);
And there is another way, use your own CSS or SCSS or LESS, but import the component CSS at the top of your component CSS system, just like below exactly like docs:
// the custom component
import React from 'react';
import Button from 'antd/es/button';
import './CustomButton.css';
const CustomButton = () => (
<div className="custom-button">
<Button type="primary">
Button
</Button>
</div>
);
// the CustomButton.css file
#import '~antd/es/button/style/css';
.custom-button {
background-color: red; // for example
}
Also, you can use the whole Ant Design CSS instead of using separately each component. I mean this:
import 'antd/dist/antd.css';
Instead of this:
import 'antd/es/button/style/css';
For this way of loading CSS, it is better to import it once at the root of the project or the CSS system.
HINT: I prefer the first, using babel plugin, it is safe, more clear and more readable.
Replace
#import './../node_modules/antd/dist/antd.css';
with
#import '~antd/dist/antd.css';
This is given in the documentation you linked.

Resources