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 encouraged to leave comments in pull requests if the existing content doesn't 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.
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',
],
};
Plugins
The removeScriptElement plugin has been renamed to removeScripts, as it not only removes the <script> element but also event handlers and script URIs. 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 APIs. 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 presetDefault = 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 affects custom plugins that use any of the following functions, where the selector (2nd) argument could reference parent or sibling nodes (i.e. div > span):
querySelectorAllquerySelectormatches
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 doesn't 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 is as follows:
// applies `selector` with context of the `childNode` and its descendants
const nodes = querySelectorAll(childNode, selector);
// applies `selector` with context of the node tree relative from `childNode`
// `rootNode` is required if result depends on a parent/sibling of `childNode`
const nodes = querySelectorAll(childNode, selector, rootNode);
// 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, have a Common JS project (you import SVGO using require), or are 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 the default export must be replaced with the named equivalent.
- 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>');