Reputation: 69681
I am building a Next.js application and looking for an icon package that works with its SSR paradigm.
After trying a few libs, I'm now working with FortAwesome/react-fontawesome, which looks promising.
The problem is when the page loads the icons are large (unstyled) and then suddenly they are styled properly. I'm trying to figure out how to get these to style server-side.
I've seen folks talk about importing a stylesheet provided by FortAwesome:
import '@fortawesome/fontawesome-svg-core/styles.css';
However, I'm unsure which file(s) this should be done in and also, Next complains when I try this:
[ error ] ./node_modules/@fortawesome/fontawesome-svg-core/styles.css 1:8 Module parse failed: Unexpected token (1:8) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file
I've looked at the CSS plugin, but this also seems like a red herring.
How can I get the font-awesome icons in this package to be styled on the server with Next.js?
Upvotes: 9
Views: 10936
Reputation: 5353
React-fontawesome has added a section on how to get FontAwesome working with Next.js.
https://github.com/FortAwesome/react-fontawesome#nextjs
Create an ./pages/_app.js
file in your project
import React from 'react'
import App, { Container } from 'next/app'
import { config } from '@fortawesome/fontawesome-svg-core'
import '@fortawesome/fontawesome-svg-core/styles.css' // Import the CSS
config.autoAddCss = false // Tell Font Awesome to skip adding the CSS automatically since it's being imported above
class MyApp extends App {
render() {
const { Component, pageProps } = this.props
return <Component {...pageProps} />
}
}
export default MyApp
or using a function component:
import { config } from '@fortawesome/fontawesome-svg-core'
import '@fortawesome/fontawesome-svg-core/styles.css' // Import the CSS
config.autoAddCss = false // Tell Font Awesome to skip adding the CSS automatically since it's being imported above
export default function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
Upvotes: 17
Reputation: 556
I had this same issue and fixed it by manually inserting Font Awesome's CSS into styles which I know will get SSR'ed correctly.
I use styled-components
, which is easy to set up with Next.js SSR, and here's how I did it:
import { createGlobalStyle } from "styled-components";
import { config, dom } from "@fortawesome/fontawesome-svg-core";
// Prevent FA from adding the CSS
// (not that it was doing it in the first place but might as well)
config.autoAddCss = false;
// Add the FA CSS as part of Global Styles
const GlobalStyles = createGlobalStyle`
${dom.css()}
`;
Upvotes: 1
Reputation: 711
There are definitely a few ways to take this problem. I solved it in my project by importing the icons I needed directly into my React app. So no Font Awesome libraries sit on the client-side, just the rendered SVGs.
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faAdobe } from '@fortawesome/free-brands-svg-icons/faAdobe'
...
return (
<FontAwesomeIcon icon={faAdobe} />
)
Font Awesome also provides a page to discuss other methods: server-side-rendering
Upvotes: 2
Reputation: 1298
Here is what I have tried so far to fix this issue in my project:
Installation of @zeit packages
Install required packages:
npm i --save @zeit/next-css
npm i --save @zeit/next-less
npm i --save @zeit/next-sass
then update next.config.js
file such as below that will support CSS import which fix the issue of loading correct styles upon loading:
const withCSS = require('@zeit/next-css')
const withLess = require('@zeit/next-less')
const withSass = require("@zeit/next-sass");
module.exports = withLess(withCSS(withSass({
webpack(config, options) {
config.module.rules.push({
test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
use: {
loader: 'url-loader',
options: {
limit: 100000
}
}
});
return config
}
})));
Installation of fontawesome packages & import CSS
Install required packages:
npm i --save @fortawesome/fontawesome-svg-core
npm i --save @fortawesome/free-solid-svg-icons
npm i --save @fortawesome/react-fontawesome
Then you can use following code within your pages extending React.Component
located under pages
directory:
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { library } from '@fortawesome/fontawesome-svg-core';
import { fas } from '@fortawesome/free-solid-svg-icons'
import '@fortawesome/fontawesome-svg-core/styles.css';
library.add(fas);
Then this is the way you can use fonts:
<FontAwesomeIcon icon={["fas", "user-tie"]} />
I may be wrong.
Upvotes: 0
Reputation: 69681
I'm going to put this as an answer, because it's a way, however I feel like there is a better solution out there, so I will not accept this one.
I created a static/css
folder, then copied the css file referenced in the question
cp node_modules/@fortawesome/fontawesome-svg-core/styles.css static/css/fortawesome.css
Then in _document.js I load the file via link
tag:
<link
rel="stylesheet"
type="text/css"
href="/static/css/fortawesome.css"
/>
I would consider this a stop-gap solution. One issue obviously is that when the underlying library updates I would need to copy over the latest version of the css file manually.
Upvotes: 1