Skip to content

Instantly share code, notes, and snippets.

@vHeemstra
Last active May 9, 2025 05:50
Show Gist options
  • Save vHeemstra/39e747eede1d0c10d0350e189f5d7724 to your computer and use it in GitHub Desktop.
Save vHeemstra/39e747eede1d0c10d0350e189f5d7724 to your computer and use it in GitHub Desktop.
Importing Font Awesome 6 as Custom Icon set in Elementor Pro

Using Font Awesome 6 as Custom Icon set in Elementor

As many already know, Elementor is very reluctant to stay up-to-date with their CMS. It still uses Font Awesome version 5 and if you don't have a Pro license for Font Awesome, it is very difficult to integrate FA6 as icons.

So to help fellow developers, here is how you can do it!

In Elementor you can import icon sets that are exported by Fontello (as ZIP).

Because Fontello does not support FA6, you have to generate this ZIP file yourself.

We will do this using Node and Gulp.

Step 1 - Create a (local) project folder

a. Create a new folder

b. Inside this folder, initiate a new NPM project that uses Gulp by following the installation documentation here.

c. Install the following dependencies:

npm install --save-dev gulp-concat gulp-rename del sass gulp-sass gulp-postcss postcss-url autoprefixer cssnano gulp-zip

Step 2 - Collect the proper Font Awesome 6 files

Download the full Font Awesome 6 repository as ZIP and extract these files to you project folder:

  • /scss/*
  • /webfonts/*
  • /metadata/icon-families.json

Step 3 - Adjust some variables

At the end of scss/_variables.scss, add these variables:

$fa-css-prefix: fa6;
$fa-font-path: "../font";
$fa-font-display: swap; // Optional

Step 4 - Add style variable declaration to each font style's SCSS at the bottom:

For example, for sharp light:

.fasl,
.#{$fa-css-prefix}-light {
  --#{$fa-css-prefix}-style: 300; // <-- Add this line with the correct font-weight number
  font-weight: 300;
}

at the end of scss/sharp-light.scss.

Do this for all font/icon styles you need.

Step 5 - Create the Gulp tasks file

Copy the source code from the gulpfile.mjs below and save this file in your project folder.


Your project folder should now look like this:

metadata/icon-families.json
node_modules/**
scss/*.scss
webfonts/*.(ttf|woff2)
package.json
gulpfile.mjs

Step 6 - Run the default Gulp task

gulp

If all goes well, you now have an output folder containing folders for each Font Awesome icon set and their zipped version.

output/brands.zip
output/brands/config.json
output/brands/css/brands.css
output/brands/font/fa-brands*

output/regular.zip
...etc

Step 7 - Import the icon sets in Elementor

Import the ZIP file of each icon set following the steps mentioned here.

DONE!

Now you can finally enjoy the latest Font Awesome icons inside your Elementor website:

image

(Although odds are Elementor will find a way to mess up their code and this will not work anymore..🤷‍♂️)

import { writeFileSync, readFileSync } from 'node:fs';
import gulp from 'gulp';
import concat from 'gulp-concat';
import rename from 'gulp-rename';
import { deleteAsync as del } from 'del';
import * as dartSass from 'sass';
import gulpSass from 'gulp-sass';
import postcss from 'gulp-postcss';
import url from "postcss-url";
import autoprefixer from 'autoprefixer';
import cssnano from 'cssnano';
import zip from 'gulp-zip';
const {
series,
parallel,
src,
dest,
} = gulp;
const sass = gulpSass(dartSass);
const pluginDir = `./`;
const outputDir = `${ pluginDir }output/`;
const iconsJSON = JSON.parse(
readFileSync(
new URL(`${ pluginDir }metadata/icon-families.json`, import.meta.url)
)
);
const fonts = [
// Free icons
'brands',
'solid',
'regular',
// Pro icons
'light',
'thin',
'duotone',
'sharp-solid',
'sharp-regular',
'sharp-light',
'sharp-thin',
].map(name => ({
name,
sources: [
`${ pluginDir }scss/fontawesome.scss`,
`${ pluginDir }scss/${name}.scss`,
name === 'duotone' ? `${pluginDir}scss/_${name}-icons.scss` : '',
].filter(s => s.length > 0),
fonts: `${ pluginDir }webfonts/fa-${name}-*`,
destination: `${ outputDir }${name}/`,
}));
// This task copies the font files and compiles the CSS for each icon set/variant.
const fontsTasks = fonts.map( font => {
const copyTask = (cb) => src( font.fonts )
.pipe( dest( `${font.destination}font/` ) )
;
copyTask.displayName = `copy font ${font.name}`;
const scssTask = () => src( font.sources )
.pipe( concat(`${font.name}.scss`) )
.pipe( sass( {
includePaths: [
`${ pluginDir }scss/`,
],
} ).on( 'error', sass.logError ) )
.pipe( postcss( [
url( {
url: "rebase"
} ),
autoprefixer( {
overrideBrowserslist: [ 'last 2 versions' ]
} ),
cssnano()
] ) )
.pipe( rename( { extname: '.css' } ) )
.pipe( dest( `${font.destination}css/` ) )
;
scssTask.displayName = `scss font ${font.name}`;
return parallel(
copyTask,
scssTask
);
});
// This task creates config JSON files for each icon set/variant.
const taskCompileConfigs = (cb) => {
const configs = fonts.map(f => f.name)
.reduce((acc, v) => {
acc[v] = {
"name": v,
"css_prefix_text": `fa${v
.split("-")
.map((vv) => vv.slice(0,1))
.join("")
} fa6-`,
"css_use_suffix": false,
"hinting": true,
"units_per_em": 1000,
"ascent": 850,
"glyphs": []
};
return acc;
}, {});
Object.entries(iconsJSON).forEach(([k, icon]) => {
const names = [k, ...(icon?.aliases?.names ?? [])];
const styles = [
icon?.svgs?.classic?.brands ? "brands" : false,
icon?.svgs?.classic?.solid ? "solid" : false,
icon?.svgs?.classic?.regular ? "regular" : false,
icon?.svgs?.classic?.light ? "light" : false,
icon?.svgs?.classic?.thin ? "thin" : false,
icon?.svgs?.duotone?.solid ? "duotone" : false,
icon?.svgs?.sharp?.solid ? "sharp-solid" : false,
icon?.svgs?.sharp?.regular ? "sharp-regular" : false,
icon?.svgs?.sharp?.light ? "sharp-light" : false,
icon?.svgs?.sharp?.thin ? "sharp-thin" : false,
].filter(s => s !== false);
const code = parseInt(icon.unicode, 16);
styles.forEach(style => {
names.forEach(name => {
configs[style].glyphs.push({
code,
css: name,
src: "fontawesome6"
});
})
});
});
Object.entries(configs).forEach(([font, configJSON]) => {
writeFileSync(`${ outputDir }${font}/config.json`, JSON.stringify(configJSON));
});
cb();
};
const zipTasks = fonts.map((font) => {
const zipTask = (cb) =>
src(`${outputDir}${font.name}/**`)
.pipe(zip(`${font.name}.zip`))
.pipe(dest(outputDir));
zipTask.displayName = `zip font ${font.name}`;
return series(zipTask);
});
// This task deletes the output folder before doing the other tasks.
const taskCleanTemp = (cb) => del( `${outputDir}/**` );
const taskDefault = series(
taskCleanTemp,
parallel( ...fontsTasks ),
taskCompileConfigs,
parallel( ...zipTasks ),
);
export {
taskDefault as default,
taskCleanTemp as clean,
taskCompileConfigs as compile,
}
@sylvaing26
Copy link

Hi dear,
I've tested your new script with Font Awesome 6.5.1 from @RobinMokry but width WP 6.5.2 and Elementor Pro 3.20.3, no icons work :(

@troycono
Copy link

troycono commented Jun 5, 2024

@sylvaing26 - Same here, Elementor Pro v3.21.3, Font Awesome 6.5.2, WordPress 6.5.3.

After uploading a single icon set, in this case "thin," all other Font Awesome icon sets now look like this:

Screenshot 2024-06-05 at 3 55 26 PM

And the "thin" icon set displays no previews whatsoever:

Screenshot 2024-06-05 at 3 55 36 PM

@github-lobster
Copy link

As @sylvaing26 and @troycono I faced issues with FontAwesome 6.5.x.

But finally I found out that the font files in the output folder are corrupt. I have no idea why as they are only copied by the gulp task!?

So I deleted the files in the “font” folder in the ZIP archive \output\brands.zip (using “brands” as an example) and replaced them with the original files from the FontAwesome repository. Now the display of the icons in the Elementor backend (Custom Icon Sets) also works.

@sylvaing26
Copy link

As @sylvaing26 and @troycono I faced issues with FontAwesome 6.5.x.

But finally I found out that the font files in the output folder are corrupt. I have no idea why as they are only copied by the gulp task!?

So I deleted the files in the “font” folder in the ZIP archive \output\brands.zip (using “brands” as an example) and replaced them with the original files from the FontAwesome repository. Now the display of the icons in the Elementor backend (Custom Icon Sets) also works.

Oh yeah very good.
Thanks !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment