Migration from v3 to v4
This is a summary of the changes necessary to migrate from SVGO v3 to SVGO v4. If you want more details or have any questions, please refer to our release notes for SVGO v4.0.0 or related pull requests. You're also encouraged to leave comments in pull requests if the existing content doesn't already answer your question.
Version Requirements
SVGO now requires Node.js >=16.0.0.
Default Behavior
The following changes have been made to default plugins, also known as preset-default.
- removeViewBox is no longer a default plugin, to preserve scalability.
- removeTitle is no longer a default plugin, to preserve accessibility.
- removeScriptElement has been renamed to removeScripts, as it not only removes the
<script>
element, but also event handlers, and script URIs.
To continue using removeViewBox or removeTitle, configure it in the SVGO config, see the README for more context, but please consider reading the warnings in the respective plugin's documentation first:
export default {
plugins: [
'preset-default', // built-in plugins enabled by default
+ 'removeViewBox',
+ 'removeTitle',
],
};
If you were using the removeScriptElement plugin, amend your SVGO config to use removeScripts instead:
export default {
plugins: [
'preset-default', // built-in plugins enabled by default
- 'removeScriptElement',
+ 'removeScripts',
],
};
Public vs Internal API
We now enforce a boundary between public and internal API. It's no longer possible to arbitrarily import any code declared by SVGO, but rather only the public API we declare as part of our semantic versioning.
There are two ways to import SVGO:
svgo
— for normal usage, such as scripts or server-side applications.svgo/browser
— for browser usage.
Browser Bundle
If you use the browser bundle, you must amend how you import it:
- import { optimize } from 'svgo/dist/svgo.browser.js';
+ import { optimize } from 'svgo/browser';
Importing Helpers or Plugins
If you import
/require
helpers, the array of built-in plugins, or a single plugin during runtime, this is now a top-level export instead:
// import helpers
- import { querySelector, querySelectorAll } from 'svgo/lib/xast.js';
+ import { querySelector, querySelectorAll } from 'svgo';
// import the array of built-in plugins
- import { builtin } from 'svgo/lib/builtin';
+ import { builtinPlugins } from 'svgo'
// getting a single plugin
- import presetDefault from 'svgo/plugins/preset-default';
+ import { builtinPlugins } from 'svgo';
+ const prefixDefault = builtinPlugins.find(plugin => plugin.name === 'preset-default');
// getting a map of plugin names to implementations
import { builtinPlugins } from 'svgo';
const pluginMap = builtinPlugins.reduce((acc, val) => acc.set(val.name, val), new Map());
Selector Helpers
Xast/CSS helpers for selecting nodes must be imported from svgo
instead, and have different behavior. This effects custom plugins that use any of the following functions, where the selector
(2nd) argument could reference parent or sibling nodes (i.e. div > span
):
querySelectorAll
querySelector
matches
If this applies to you, then you need to pass a Map
of nodes to their parent node as a third argument.
A helper has been provided named #mapNodesToParents
, which does this for you. This can be used to easily migrate to the new API. If you're not sure if you need it, then it's safer to take this approach. The third argument won't be necessary if selector
does not traverse nodes, for example querying using one or more attributes of a single node.
- import { querySelectorAll } from 'svgo';
- const nodes = querySelectorAll(childNode, selector);
+ import { querySelectorAll, mapNodesToParents } from 'svgo';
+ const nodes = querySelectorAll(childNode, selector, mapNodesToParents(rootNode));
The new API for these functions are as follows:
// applies `selector` with the context of the `childNode` and its descendants
const nodes = querySelectorAll(childNode, selector);
// applies `selector` with the context of the entire node tree relative from `childNode`
// the `rootNode` is required if the result of `selector` may depend on the parent or sibling of `childNode`
const nodes = querySelectorAll(childNode, selector, rootNode);
// this usage has the same behavior as v3, as `rootNode` is already the entire node tree
const nodes = querySelectorAll(rootNode, selector);
Named vs Default Exports
SVGO now only has named exports, there are no default exports in the public API.
If you use SVGO from the CLI, or have a Common JS project (you import SVGO using require
), or if you were already using named exports, you don't have to do anything.
If one way or another you're using the import
keyword to import SVGO, then any instance where you use a default export must be switched for the named equivilent.
- import svgo from 'svgo';
- svgo.optimize('<svg></svg>');
// Option 1. Use named exports!
+ import { optimize } from 'svgo';
+ optimize('<svg></svg>');
// Option 2. Or import everything as svgo!
+ import * as svgo from 'svgo';
+ svgo.optimize('<svg></svg>');