icon-prerender
v0.1.2
Published
A plugin to prerender your SVG icons at compile time, rather than making the client fetch them during runtime.
Downloads
7
Maintainers
Readme
🚀 Icon Prerender
A framework-agnostic plugin (likely compatible with your build tool) that prerenders your SVG icons at build time so your clients don't have to fetch them during browsing. Designed for ease-of-use and maximum performance.
Why?
There are several icon libraries out there. However, it is rare to find one that ticks all the following:
- Works at build time (to minimise bundle size)
- Does not affect your bundle size at all
- Optimises SVGs at build time
- Requires no configuration or fiddling with other configuration options
- Allows you to simply specify icons in the template e.g., `mdi:chevron-right
- Does not require importing a bunch of components or creating icon sets
This library is heavily inspired by astro-icon
and essentially works the same except:
icon-prerender
works for any framework, even raw HTML (provided you use a bundler)astro-icon
provides icon components -icon-prerender
allows you to use just HTMLicon-prerender
provides much more flexibility on how icons are specifiedicon-prerender
allows you to inline raw SVG elements
Again, astro-icon
works in this way, but only supports .astro
components and does not work with server-side rendering.
Installation
This plugin requires @iconify/json
as a peer dependency:
npm i --save-dev icon-prerender @iconify/json
yarn add -D icon-prerender @iconify/json
pnpm i -D icon-prerender @iconify/json
I also recommend installing and enabling the iconify-intellisense
VSCode extension by Anthony Fu.
Usage
In the template, you can define an icon to prerender as either:
- One of the following HTML elements with a
data-icon
attribute:<div>
<span>
<figure>
<img>
<svg>
- any custom element tag
- Any
<svg />
element wrapped around ause
tag with either ahref
orxlink:href
attribute i.e.:
<svg>
<use href="assets/icon.svg#id"></use>
</svg>
- Note that for it to be valid HTML, you need to point to the ID of the element in the SVG file
- This suffix is stripped when resolving the path to the raw SVG item
This last feather sets icon-prerender
from other icon libraries as this is valid HTML - if you disabled icon-prerender
, the above would still work (assuming the href
points to a valid path). The only difference would be it would have to make an extra network request during runtime to fetch the SVG and would then have to render it.
So, the cases above describe the default resolution algorithm; by default, these are the only elements that will be transformed into <svg />
elements. See "Configuration" to see how this can be changed.
Additionally, the data-icon
attribute can either be:
- A
[pack]:[name]
string specifying the icon pack and the specific icon in the pack - A relative path to a
.svg
file- Note that this is relative to the build output directory - you can modify the asset chunk names to make the filenames more predictable if needed
- This also means there is no need to register icon sets - just set the path to the SVG file and it will be inlined
- An external URL pointing to an SVG file - this can be an API endpoint or simply a statically hosted SVG file
- The API must return an raw SVG (not JSON or HTML) and must contain
svg
in thecontent-type
header
- The API must return an raw SVG (not JSON or HTML) and must contain
Whatever you provide to data-icon
will be resolved and prerendered at build time.
Any attributes defined on the original element (apart from data-icon
unless it is a [pack]:[name]
string) will be preserved and will override identical attributes in the resolved SVG element, except:
- The
class
will be concatenated from both elements - Any children will be merged from both elements with children in the resolved SVG appearing lower in the template
- In the case of a
<use>
tag wrapped inside an<svg>
, the<use>
tag will be removed
- In the case of a
Note that icons can be nested inside each other, however, children will be resolved first. So the innermost icon will be prerendered first.
Then, you use the include the appropriate plugin with in your bundler's config:
Astro
import { defineConfig } from "astro/config";
import icons from "icon-prerender/astro";
export default defineConfig({
integrations: [icons()],
})
Vite
import { defineConfig } from "vite";
import icons from "icon-prerender/vite";
export default defineConfig({
plugins: [icons()],
})
Rollup
import { defineConfig } from "rollup";
import icons from "icon-prerender/rollup";
export default defineConfig({
plugins: [icons()],
})
esbuild
import esbuild from "esbuild";
import icons from "icon-prerender/esbuild";
esbuild.build({
plugins: [icons()],
}).catch(() => process.exit(1));
Webpack
In CommonJS form:
const IconPrerenderPluginWebpackPlugin = require("icon-prerender/webpack");
module.exports = {
plugins: [new IconPrerenderPluginWebpackPlugin()],
}
Configuration
include
- A regex, an array of strings (or regexes) of HTML attributes (can be custom) to filter elements on- If an attribute of any HTML element matches anything inside this array, it will be transformed into an SVG element.
- default
undefined
- enables default filtering
exclude
- A regex, an array of strings (or regexes) of HTML attributes (can be custom) to filter elements on- If an attribute of any HTML element matches anything inside this array, it will not be transformed into an SVG element.
- default:
undefined
- enables default filtering
Note: specifying include
or exclude
will not override default filtering - they are used to either include extra elements, or exclude elements that would have been included for transformation by default.
Roadmap
[ ] Allow consumers to disable default resolution via a new plugin option
- Completely custom resolution would then be achieved by simply using
include
andexclude
in tandem with this new plugin option
- Completely custom resolution would then be achieved by simply using
[ ] Add more component tests, especially with larger files
Have any other ideas? Make a suggestion in the Discussions tab.
Contributing
To get started with development, you will need an editor (VS Code is recommended), a browser that runs JavaScript and some extra prerequisites:
To get started with contributing to this project, first fork this git repository:
git clone https://github.com/Ernxst/icon-prerender.git
Then, install dependencies and start coding.
Submitting Improvements
If you have a suggestion that would make this app better, please fork the repo and create a pull request. You can also
simply open an issue with the tag "enhancement
".
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature
) - Commit your Changes (
git commit -m 'Add some AmazingFeature'
) - Push to the Branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
License
Distributed under the MIT License. See LICENSE
for more information.