Customizing Strapi Admin UI

I've been exploring "headless" Content Management Systems (CMS) for a while now. Without going too much into details about my results (so far) I can safely say I have found a very strong contender for the "javascript wordpress killer" title: strapi.

Even though it's still in its alpha stage, it is fairly stable, quite intuitive, and flexible for extending both the front-end and the back-end portions of the CMS itself. Oh, and very importantly, well documented.

I currently have a use-case for strapi as the CMS for my open source ui kit for React.js, kune-ui. As I was planning out how strapi and kune-ui's website/documentation would fit together, I wondered: "what if I wanted to extend strapi's admin panel with some of kune-ui's magic?"

The proof-of-concept test was simple, change strapi's left menu header's (where the logo is located) background from blue to badass green (literally #bada55)...

Image depicting the color change of strapi's left menu header's background

It did take me a bit of trial and error, but ultimately I found the answer looking at strapi's contribution guide.

As previously mentioned strapi is still at an alpha stage, and even though a beta release is scheduled for the end of April (which I made sure to show my excitement for), theming still seems to be an after-thought in the development road-map. Which is not to say that customization is not possible, in fact, it's fairly simple.

Before getting started there's three things you need to keep in mind:

  1. It's better if you use Node's latest LTS version (currently 10.x), you can take a look at this guide on how to setup nvm to keep multiple versions of Node in your system and switch them at will.
  2. You will be using a clone of strapi's github repo to work on top of instead of using strapi's cli package.
  3. Aside from the repo, you will need two strapi apps (one for developing the admin, the other being your own app).

With that said, let's go over the step-by-step of customizing your strapi admin CMS...

Remove strapi's global cli package

If you followed strapi's getting started guide, chances are you installed the strapi npm package globally. You need to uninstall it to be able to extend the admin using the source from github as your base:

$ npm uninstall -g strapi

If you didn't install strapi using npm i -g, then you can skip this step.

Clone strapi repo and setup an admin-dev app

Once you've made sure that the strapi package is not installed globally, clone the repo:

$ git clone

Strapi has some really neat bootstraping npm scripts, and you are going to run the included setup script to make strapi available as a cli command, but pointing to the repository source code you just cloned:

$ cd strapi
$ npm run setup && cd ..

The setup process does take a while, but with a little patience you'll get a success prompt, after which you can create an admin development app which you will use to customize strapi's admin interface:

$ strapi new admin-dev --dev

NOTE: The --dev flag is the reason we use two apps; once an app is created with the --dev flag it is a bit cumbersome to turn it into a "normal" app, so it's just easier to have an app to customize the admin with, and another to be your actual strapi based app.

When the admin-dev app finishes spinning up you will get the following warning:

[2019-02-24T10:18:03.956Z] warn ⚠️  The admin panel is unavailable... Impossible to open it in the browser.

It's perfectly ok, as we are actually going to be spinning up the admin separately.

Spinning up the admin dev server and customizing it

When you create a strapi app with the --dev flag, one thing you might notice about the app's folder structure is that the admin directory is not a directory but a symlink:

Image depicting strapi's folder structure including symlink

This symlink points to the admin sub-package under the strapi repo you cloned and setup in the previous step. This is important to note as it means that if you created a different app with the --dev flag, you would essentially be working on the same admin source code and thus probably not getting the intended result when creating the second app itself.

In any case, to spin up the dev server we are going to be using to see our changes to the admin front-end, simply open up a new terminal (the admin-dev app should still be running) and run the following:

$ cd /path/to/admin-dev
$ cd admin
$ npm start

When it's done setting up your default browser should open up a new tab with the address: http://localhost:4000/admin

Now simply follow the instructions to create a new user and log in.

Boom, now you have a hot-reloading development version of the admin front-end on port 4000:

Now on to our proof of concept, under the admin-dev app directory you will find the following sub-path: admin/admin/src/components/LeftMenuHeader

In it you will find a styles.scss file. Open that file and change the background property on the .leftMenuHeader:

.leftMenuHeader { /* stylelint-ignore */
  /* ... */
  background: #bada55;

Save it and bask in your hot-realoding glory:

animation depicting the change of the left menu header background when styles.scss file saved

Create your final strapi app with custom admin ui

Now that you have a customized admin, stop your admin-dev and admin processes (ctrl-c) and since your system reference to the strapi command points to the repository you have been customizing, if you run the following in your root work directory:

$ strapi new my-customized-site

It will create a new strapi site with a packaged build of the admin ui within it (instead of a symlink).

Now, let's be clear, since the admin directory under my-customized-site is a packaged build of the admin, if you change the admin-dev/admin package now, the changes will not be reflected on my-customized-site/admin.

In order to update my-customized-site from now on, you have to build the admin package under admin-dev and overwrite the build directory under my-customized-site/admin/admin.

Before running the last few commands, let's be clear that I am assuming that your work directory currently has the following structure:

 ↳ strapi
 ↳ admin-dev
   ↳ admin (symlink)
   ↳ ...
 ↳ my-customized-site
   ↳ admin
   ↳ ...

With that in mind, now run:

$ cd admin-dev/admin
$ npm run build
$ cd ../..
$ rm -rf my-customized-site/admin/admin/build
$ cp -r admin-dev/admin/admin/build my-customized-site/admin/admin/
$ cd my-customized-site
$ strapi start

And that's all you need to do from now on to update your final app.

Happy Coding!

Show Comments