For a NextJS project I'm working on at the moment the decision was made to get up and running quickly using IBM's pretty excellent Carbon design system[1]. On the face of it, this should have been a pretty simple process. After all, I've configured Next to use much more "complex" and twisty tools like Tailwind before without a second thought, so how hard could Carbon be?
Turns out, it was a bit of a headache. To be clear, this wasn't any fault of the Carbon installation process or the team behind it. Nor was it an issue with Next. If anything, both groups have tried to make things as easy as possible. It's just that, in doing so, they have inadvertently made it harder to get the various parts to talk to one another, whilst actual issues became obfuscated by slightly roundabout documentation (in places) and no real community guidance – hence this article.
That said, I'm definitely no expert in any of the tools or technologies covered here, so consider everything served with a handy pinch of salt. All I can say is that after about five hours of debugging, I now have a NextJS repository that can import, display, and extend Carbon components. Hopefully these steps can help others achieve the same outcome 😉
The Prerequisites
I'm not aiming to write a full-fat guide or tutorial here, so I'm going to assume that you already have a NextJS project set up (I'm specifically using Next v10), hooked up to whatever CI pipeline you want, and version controlled using Git. Similarly, you'll need to have npm installed and preferably some kind of IDE. Oh, and I personally use Windows 10, though I don't think anything I'm doing will be any different on Mac or Linux.
Basically, as long as you can run some kind of local command (e.g. npm run dev
) and see a default Next site spin up on localhost, you're ready for the next steps 🎉 If not, check out some of the further reading below first.
Installing Carbon
Carbon is split across a few different packages, so depending on exactly what you need there is some flexibility. For most scenarios though, you'll want to run the following to install the core components, React-specific stuff, and the UI icons that the design system uses:
npm install carbon-components carbon-components-react carbon-icons
If you're using TypeScript (like we were) you can then grab the Directly Typed packages with:
npm install @types/carbon-components npm install @types/carbon-components-react
Great, that covers all the main design system files and functionality, but there is one more third-party dependency that Next will need to make sense of things: Sass. Let's grab that as well:
npm install sass
Luckily, Next comes preinstalled with a lot of the additional dependency needs that Carbon normally asks for, so you won't need to worry about other tools mentioned in their docs (i.e. webpack). It also magically sorts out the Sass integration, all you need to do is point it in the right direction.
To do that, create a new file in the root directory of your project and name it styles.scss
. Open it up and paste in the following, save it, and forget it about forever:
@import './node_modules/carbon-components/scss/globals/scss/styles.scss';
The last step is to import those global styles into your app itself, so open up the _app.tsx
(or _app.jsx
if not using TypeScript) in your pages
folder and import it at the top of the file:
import '../styles.scss'
And that's it. Seriously, Carbon should just work at this point 🎉
Using Carbon Components
Right, but let's just make sure of that first by actually using a Carbon component. Because it's an incredibly simple one (and only a single line of code), let's start with a loading spinner. Open up any page template (e.g. index.tsx
or index.jsx
) and import the Loading component at the top:
import { Loading } from 'carbon-components-react'
Then, within your returned JSX for the existing page template, add the following anywhere:
<Loading description="Loading indicator" withOverlay={false} />
Now (if you haven't already) open up the site on localhost and you should hopefully see one of these:
With the site open, we can also just check that attributes are being passed correctly by amending the Loading
component like so:
<Loading description="Loading indicator" withOverlay={false} small />
Go back to your browser and you should see the spinner is now only about one character tall 👍