diff --git a/astro.sidebar.ts b/astro.sidebar.ts index f2bcf97c84029..9cc4c15349db2 100644 --- a/astro.sidebar.ts +++ b/astro.sidebar.ts @@ -158,6 +158,7 @@ export const sidebar = [ 'reference/experimental-flags/svg-optimization', 'reference/experimental-flags/queued-rendering', 'reference/experimental-flags/rust-compiler', + 'reference/experimental-flags/logger', ], }), 'reference/legacy-flags', diff --git a/src/content/docs/en/guides/fonts.mdx b/src/content/docs/en/guides/fonts.mdx index a9da7a2b776a1..4b43e3a1893de 100644 --- a/src/content/docs/en/guides/fonts.mdx +++ b/src/content/docs/en/guides/fonts.mdx @@ -275,23 +275,20 @@ You can also opt out of the default optimization by setting [`font.optimizedFall ## Accessing font data programmatically -Astro exposes a low-level API for accessing font family data programmatically through the [`fontData`](/en/reference/modules/astro-assets/#fontdata) object. This can be useful for advanced use cases where you need direct access to font files, such as generating OpenGraph images with [Satori](https://github.com/vercel/satori) in an [API Route](/en/guides/endpoints/#server-endpoints-api-routes). +Astro exposes low-level APIs for accessing data programmatically: -This low-level API gives you access to all font files downloaded by Astro for your project, along with their metadata. This means that you are responsible for filtering font files to find the specific file you need, and for resolving the file path to use based on the build output structure. +- Font family data through the [`fontData`](/en/reference/modules/astro-assets/#fontdata) object +- Font file URLs with the [`experimental_getFontFileURL()`](/en/reference/modules/astro-assets/#experimental_getfontfileurl) function. -:::note -The current API has a [known limitation that requires you to manually load the font file](https://github.com/withastro/astro/issues/16139) from the output path at build time. +This can be useful for advanced use cases where you need direct access to font files, such as generating OpenGraph images with [Satori](https://github.com/vercel/satori) in an [API Route](/en/guides/endpoints/#server-endpoints-api-routes). -A new API is being developed to simplify this process and will be available in a future release. You can subscribe to the GitHub issue to follow its progress. -::: +The `fontData` object gives you access to all font files downloaded by Astro for your project, along with their metadata. This means that you are responsible for filtering font files to find the specific file you need, and for fetching data after resolving URLs. The following example generates an OpenGraph image in a static file endpoint, assuming that only [one font and its format have been configured](/en/reference/configuration-reference/#fontformats) with a [format supported by Satori](https://github.com/vercel/satori?tab=readme-ov-file#fonts): -```tsx title="src/pages/og.png.ts" {2} "fontData[\"--font-roboto\"]" +```tsx title="src/pages/og.png.ts" {2,14-15} "fontData[\"--font-roboto\"]" import type { APIRoute } from "astro"; -import { fontData } from "astro:assets"; -import { outDir } from "astro:config/server"; -import { readFile } from "node:fs/promises"; +import { fontData, experimental_getFontFileURL } from "astro:assets"; import satori from "satori"; import { html } from "satori-html"; import sharp from "sharp"; @@ -303,9 +300,8 @@ export const GET: APIRoute = async (context) => { throw new Error("Cannot find the font path."); } - const data = import.meta.env.DEV - ? await fetch(new URL(fontPath, context.url.origin)).then(async (res) => res.arrayBuffer()) - : await readFile(new URL(`.${fontPath}`, outDir)); + const url = experimental_getFontFileURL(fontPath, context.url); + const data = await fetch(url).then((res) => res.arrayBuffer()); const svg = await satori( html`
hello, world
`, diff --git a/src/content/docs/en/reference/adapter-reference.mdx b/src/content/docs/en/reference/adapter-reference.mdx index 74114eefbb129..359fb442dc595 100644 --- a/src/content/docs/en/reference/adapter-reference.mdx +++ b/src/content/docs/en/reference/adapter-reference.mdx @@ -1138,6 +1138,16 @@ Defines an instance of the Astro logger that can be used to write logs when the Describes the [configured HTTP response headers](/en/reference/configuration-reference/#serverheaders). +#### `PreviewServerParams.allowedHosts` + +

+ +**Type:** `string[] | true | undefined`
+ +

+ +Describes the [configured allowed hosts](/en/reference/configuration-reference/#serverallowedhosts) that the preview server should respond to. + #### `PreviewServerParams.root`

diff --git a/src/content/docs/en/reference/configuration-reference.mdx b/src/content/docs/en/reference/configuration-reference.mdx index 2039bb4c8f594..45614cb7aaa41 100644 --- a/src/content/docs/en/reference/configuration-reference.mdx +++ b/src/content/docs/en/reference/configuration-reference.mdx @@ -331,20 +331,23 @@ The value can be either an absolute file system path or a path relative to the p

-**Type:** `boolean`
+**Type:** `boolean | "jsx"`
**Default:** `true`

-This is an option to minify your HTML output and reduce the size of your HTML files. +Controls how Astro handles whitespace in your HTML. This affects both development mode and the final build output. + +By default, Astro removes whitespace from your HTML, including line breaks, in a lossless manner from `.astro` components. Some whitespace may be preserved as needed to maintain the visual rendering of your HTML. -By default, Astro removes whitespace from your HTML, including line breaks, from `.astro` components in a lossless manner. -Some whitespace may be kept as needed to preserve the visual rendering of your HTML. This occurs both in development mode and in the final build. +Setting this option to `"jsx"` instead applies the JSX whitespace stripping rules used by frameworks like React. Leading and trailing whitespace is only preserved when explicitly included in the source code through constructs such as `{" "}`, and is otherwise removed entirely. -To disable HTML compression, set `compressHTML` to false. +Setting this option to false disables HTML compression and preserves all whitespace. ```js { compressHTML: false + // or: + // compressHTML: 'jsx' } ``` diff --git a/src/content/docs/en/reference/error-reference.mdx b/src/content/docs/en/reference/error-reference.mdx index 0742799f499d5..43b51cef5a5fe 100644 --- a/src/content/docs/en/reference/error-reference.mdx +++ b/src/content/docs/en/reference/error-reference.mdx @@ -100,7 +100,11 @@ The following reference is a complete list of the errors you may encounter while - [**CannotDetermineWeightAndStyleFromFontFile**](/en/reference/errors/cannot-determine-weight-and-style-from-font-file/)
Cannot determine weight and style from font file. - [**CannotFetchFontFile**](/en/reference/errors/cannot-fetch-font-file/)
Cannot fetch the given font file. - [**FontFamilyNotFound**](/en/reference/errors/font-family-not-found/)
Font family not found +- [**FontFileUrlNotFound**](/en/reference/errors/font-file-url-not-found/)
Font file URL not found +- [**MissingGetFontFileRequestUrl**](/en/reference/errors/missing-get-font-file-request-url/)
`experimental_getFontFileURL()` requires the request URL with on-demand rendering. - [**UnavailableAstroGlobal**](/en/reference/errors/unavailable-astro-global/)
Unavailable Astro global in getStaticPaths() +- [**UnableToLoadLogger**](/en/reference/errors/unable-to-load-logger/)
Unable to load the logger. +- [**LoggerConfigurationNotSerializable**](/en/reference/errors/logger-configuration-not-serializable/)
The configuration of the logger is not serializable ## CSS Errors diff --git a/src/content/docs/en/reference/errors/cannot-optimize-svg.mdx b/src/content/docs/en/reference/errors/cannot-optimize-svg.mdx index b978e3a0b265f..7a9aa83f50bfa 100644 --- a/src/content/docs/en/reference/errors/cannot-optimize-svg.mdx +++ b/src/content/docs/en/reference/errors/cannot-optimize-svg.mdx @@ -13,7 +13,7 @@ import DontEditWarning from '~/components/DontEditWarning.astro' -> An error occurred while optimizing the SVG file with SVGO. +> An error occurred while optimizing the SVG file with the optimizer. diff --git a/src/content/docs/en/reference/errors/font-file-url-not-found.mdx b/src/content/docs/en/reference/errors/font-file-url-not-found.mdx new file mode 100644 index 0000000000000..7a1eb678b0b74 --- /dev/null +++ b/src/content/docs/en/reference/errors/font-file-url-not-found.mdx @@ -0,0 +1,22 @@ +--- +# NOTE: This file is auto-generated from 'scripts/error-docgen.mjs' +# Do not make edits to it directly, they will be overwritten. +# Instead, change this file: https://github.com/withastro/astro/blob/main/packages/astro/src/core/errors/errors-data.ts +# Translators, please remove this note and the component. + +title: Font file URL not found +i18nReady: true +githubURL: https://github.com/withastro/astro/blob/main/packages/astro/src/core/errors/errors-data.ts +--- +import DontEditWarning from '~/components/DontEditWarning.astro' + + + + +> The URL passed to the `experimental_getFontFileURL()` function is invalid. + +## What went wrong? +Font file URL not found + + + diff --git a/src/content/docs/en/reference/errors/logger-configuration-not-serializable.mdx b/src/content/docs/en/reference/errors/logger-configuration-not-serializable.mdx new file mode 100644 index 0000000000000..287e4d28ec5b2 --- /dev/null +++ b/src/content/docs/en/reference/errors/logger-configuration-not-serializable.mdx @@ -0,0 +1,22 @@ +--- +# NOTE: This file is auto-generated from 'scripts/error-docgen.mjs' +# Do not make edits to it directly, they will be overwritten. +# Instead, change this file: https://github.com/withastro/astro/blob/main/packages/astro/src/core/errors/errors-data.ts +# Translators, please remove this note and the component. + +title: The configuration of the logger is not serializable +i18nReady: true +githubURL: https://github.com/withastro/astro/blob/main/packages/astro/src/core/errors/errors-data.ts +--- +import DontEditWarning from '~/components/DontEditWarning.astro' + + + + +> The configuration of the logger is not serializable. + +## What went wrong? +The configuration of the logger is not serializable. + + + diff --git a/src/content/docs/en/reference/errors/missing-get-font-file-request-url.mdx b/src/content/docs/en/reference/errors/missing-get-font-file-request-url.mdx new file mode 100644 index 0000000000000..3b09f6d42cb22 --- /dev/null +++ b/src/content/docs/en/reference/errors/missing-get-font-file-request-url.mdx @@ -0,0 +1,20 @@ +--- +# NOTE: This file is auto-generated from 'scripts/error-docgen.mjs' +# Do not make edits to it directly, they will be overwritten. +# Instead, change this file: https://github.com/withastro/astro/blob/main/packages/astro/src/core/errors/errors-data.ts +# Translators, please remove this note and the component. + +title: experimental_getFontFileURL() requires the request URL with on-demand rendering. +i18nReady: true +githubURL: https://github.com/withastro/astro/blob/main/packages/astro/src/core/errors/errors-data.ts +--- +import DontEditWarning from '~/components/DontEditWarning.astro' + + + + +## What went wrong? +`experimental_getFontFileURL()` requires the request URL with on-demand rendering. + + + diff --git a/src/content/docs/en/reference/errors/unable-to-load-logger.mdx b/src/content/docs/en/reference/errors/unable-to-load-logger.mdx new file mode 100644 index 0000000000000..f376f568d66da --- /dev/null +++ b/src/content/docs/en/reference/errors/unable-to-load-logger.mdx @@ -0,0 +1,22 @@ +--- +# NOTE: This file is auto-generated from 'scripts/error-docgen.mjs' +# Do not make edits to it directly, they will be overwritten. +# Instead, change this file: https://github.com/withastro/astro/blob/main/packages/astro/src/core/errors/errors-data.ts +# Translators, please remove this note and the component. + +title: Unable to load the logger. +i18nReady: true +githubURL: https://github.com/withastro/astro/blob/main/packages/astro/src/core/errors/errors-data.ts +--- +import DontEditWarning from '~/components/DontEditWarning.astro' + + + + +> Couldn't load the logger at the given path. + +## What went wrong? +Unable to load the logger. + + + diff --git a/src/content/docs/en/reference/experimental-flags/logger.mdx b/src/content/docs/en/reference/experimental-flags/logger.mdx new file mode 100644 index 0000000000000..8f1be3cba772c --- /dev/null +++ b/src/content/docs/en/reference/experimental-flags/logger.mdx @@ -0,0 +1,328 @@ +--- +title: Experimental logger +sidebar: + label: Logger +i18nReady: true +--- + +import Since from '~/components/Since.astro'; + +

+ +**Type:** `object`
+**Default:** `undefined`
+ +

+ +Enables an experimental, custom logger that can be controlled by the user. + +When provided, the user has total control over the logs emitted by Astro. Additionally, the feature comes with some built-in loggers that can be used via the new `logHandlers`. + +The following example enables the built-in JSON logger, with a pretty output: + +```js title="astro.config.mjs" {5} ins="logHandlers" +import { defineConfig, logHandlers } from 'astro/config'; + +export default defineConfig({ + experimental: { + logger: logHandlers.json({ pretty: true }) + } +}); +``` + +Alternatively, you can enable JSON logging for the `dev`, `build`, and `sync` commands using the `--experimentalJson` flag: + +```shell +astro dev --experimentalJson +astro sync --experimentalJson +astro build --experimentalJson +``` + + +## Built-in loggers + +The feature comes with three built-in loggers. + +### `logHandlers.json` + +A logger that outputs messages in a JSON format. A log would look like this: +```json +{ "message": "", "label": "router", "level": "info", "time": "" } +``` + +#### JSON logger options + +

+**Type:** `{ pretty: boolean; level: AstroLoggerLevel; }`
+**Default:** `{ pretty: false, level: 'info' }` + +

+ +The `json` logger accepts the following options: + +- `pretty`: when `true`, the JSON log is printed on multiple lines. Defaults to `false`. +- `level`: the [level](#log-level) of logs that should be printed. + +```js title="astro.config.mjs" {5} ins="json" +import { defineConfig, logHandlers } from 'astro/config'; + +export default defineConfig({ + experimental: { + logger: logHandlers.json({ pretty: true }) + } +}); +``` + +### `logHandlers.console` + +A logger that prints messages using the `console` as its destination. Based on the level of the message, it uses different channels: + +- `error` messages are printed using `console.error()`. +- `warn` messages are printed using `console.warn()`. +- `info` messages are printed using `console.info()`. + +#### Console logger options + +

+**Type:** `{ level: AstroLoggerLevel }`
+**Default:** `{ level: 'info' }` + +

+ +The `console` logger accepts the following options: + +- `level`: the [level](#log-level) of logs that should be printed. + +```js title="astro.config.mjs" {5} ins="console" +import { defineConfig, logHandlers } from 'astro/config'; + +export default defineConfig({ + experimental: { + logger: logHandlers.console({ level: 'warn' }) + } +}); +``` + +### `logHandlers.node` + +A logger that prints messages to [`process.stdout`](https://nodejs.org/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/api/process.html#processstderr). Level `error` messages are printed to `stderr`, while the others are printed to `stdout`. + +This is Astro's default logger. + +#### Node logger options + +

+**Type:** `{ level: AstroLoggerLevel }`
+**Default:** `{ level: 'info' }` + +

+ +The `node` logger accepts the following options: + +- `level`: the [level](#log-level) of logs that should be printed. + +```js title="astro.config.mjs" {5} ins="node" +import { defineConfig, logHandlers } from 'astro/config'; + +export default defineConfig({ + experimental: { + logger: logHandlers.node({ level: 'warn' }) + } +}); +``` + +### `logHandlers.compose` + +A particular function that allows configuring multiple loggers in an arbitrary order. The same message is broadcast to all loggers. + +The following example composes the console logger and JSON logger using the default log level: + +```js title="astro.config.mjs" +import { defineConfig, logHandlers } from 'astro/config'; + +export default defineConfig({ + experimental: { + logger: logHandlers.compose( + logHandlers.console(), + logHandlers.json() + ) + } +}); +``` + +## Custom loggers + +You can create a custom logger by providing the correct configuration to the `logger` setting. It accepts an object with a mandatory `entrypoint`, the module where the logger is exported, and an optional configuration to pass to the logger. The configuration must be serializable. + +The logger function must be exported as `default`. + +When you define a custom logger, you are in charge of all logs, even the ones emitted by Astro. + +The following example defines a custom logger exported by the `@org/custom-logger` package and accepting only one parameter to configure the logging `level`: + +```js title="astro.config.mjs" +import { defineConfig } from 'astro/config'; + +export default defineConfig({ + experimental: { + logger: { + entrypoint: "@org/custom-logger", + config: { + level: "warn" + } + } + } +}); +``` + +The following example implements a minimal logger returning an [`AstroLoggerDestination` object](#astrologgerdestination) with the required `write()` function: + +```ts title="@org/custom-logger/index.ts" +import type { + AstroLoggerLevel, + AstroLoggerDestination, + AstroLoggerMessage +} from "astro"; +import { matchesLevel } from "astro/logger"; + +type LoggerOptions = { + level: AstroLoggerLevel +} + +function orgLogger(options: LoggerOptions = {}): AstroLoggerDestination { + const { level = 'info' } = options; + return { + write(message: AstroLoggerMessage) { + // Use this utility to understand if the message should be printed + if (matchesLevel(message.level, level)) { + // log message somewhere and take the level into consideration + } + } + } +} + +export default orgLogger; +``` + +## Runtime + +The [context object](/en/reference/api-reference/#the-context-object) now exposes a `logger` object containing the following functions: + +- `error()`, which emits a message with `error` level. +- `warn()`, which emits a message with `warn` level. +- `info()`, which emits a message with `info` level. + +```astro +--- +Astro.logger.error("This is an error"); +Astro.logger.warn("This is a warning"); +Astro.logger.info("This is an info"); +--- +``` + +## Log level + +A level is an internal, arbitrary score assigned to each message. When a logger is configured with a certain level, only the messages with a level equal to or higher are printed. + +There are three levels, from the highest to the lowest score: +1. `error` +2. `warn` +3. `info` + +The following example configures the JSON logger to print only messages that have the `warn` level or higher: + +```js title="astro.config.mjs" {5} ins='level: "warn"' +import { defineConfig, logHandlers } from 'astro/config'; + +export default defineConfig({ + experimental: { + logger: logHandlers.json({ level: "warn" }) + } +}); +``` + +The `astro/logger` package exposes a [`matchesLevel()`](#matcheslevel) helper to check the log level. This can be useful when [building a custom logger](#custom-loggers). + +```js +import { matchesLevel } from "astro/logger"; + +matchesLevel("error", "info"); +``` + + +## Types reference + +The following types can be imported from the `astro` specifier. + +### `AstroLoggerDestination` + +This is the interface that custom loggers must implement. + +#### `AstroLoggerDestination.write()` + +

+ +**Type:** `(message: AstroLoggerMessage) => void` +

+ +A mandatory method called for each log and accepting an [`AstroLoggerMessage`](#astrologgermessage). + +#### `AstroLoggerDestination.flush()` + +

+ +**Type:** `() => Promise | void` +

+ +An optional function called at the end of each request. This is useful for advanced loggers that need to flush log messages while keeping the connection to the destination alive. + +#### `AstroLoggerDestination.close()` + +

+ +**Type:** `() => Promise | void` +

+ +An optional function called before a server is shut down. This function is usually called by adapters such as `@astrojs/node`. + +### `AstroLoggerLevel` + +The level of the message. Available variants: +- `'debug'` +- `'info'` +- `'warn'` +- `'error'` +- `'silent'` + +### `AstroLoggerMessage` + +

+ +**Type:** `{ label: string | null; level: AstroLoggerLevel; message: string; newLine: boolean; }` +

+The incoming object from the [`AstroLoggerDestination.write()`](#astrologgerdestinationwrite) function: +- `message`: the message being logged. +- `level`: the level of the message. +- `label`: an arbitrary label assigned to the log message. +- `newLine`: whether this message should add a trailing newline. + +## APIs reference + +The following APIs can be imported from the `astro/logger` specifier. + +### `matchesLevel` + +

+ +**Type:** `matchesLevel(messageLevel: AstroLoggerLevel, configuredLevel: AstroLoggerLevel) => boolean` +

+ +Given two [log levels](#log-level), it returns whether the first level matches the second level. + +```js +import { matchesLevel } from "astro/logger"; + +matchesLevel("error", "info"); // true +matchesLevel("info", "error"); // false + +``` diff --git a/src/content/docs/en/reference/experimental-flags/svg-optimization.mdx b/src/content/docs/en/reference/experimental-flags/svg-optimization.mdx index 5a9c2c9229667..f7a26412067ac 100644 --- a/src/content/docs/en/reference/experimental-flags/svg-optimization.mdx +++ b/src/content/docs/en/reference/experimental-flags/svg-optimization.mdx @@ -9,30 +9,30 @@ import Since from '~/components/Since.astro'

-**Type:** `boolean | object`
+**Type:** `SvgOptimizer`
**Default:** `false`

-This experimental feature enables automatic optimization of your [SVG components](/en/guides/images/#svg-components) using [SVGO](https://svgo.dev/) during build time. +This experimental feature enables automatic optimization of your [SVG components](/en/guides/images/#svg-components) at build time. When enabled, your imported SVG files used as components will be optimized for smaller file sizes and better performance while maintaining visual quality. This can significantly reduce the size of your SVG assets by removing unnecessary metadata, comments, and redundant code. -To enable this feature with default settings, set it to `true` in your Astro config: +To enable this feature, import the `svgoOptimizer()` helper in your Astro config and assign it to the experimental `svgOptimizer` flag: ```js title="astro.config.mjs" ins={5} -import { defineConfig } from "astro/config" +import { defineConfig, svgoOptimizer } from "astro/config"; export default defineConfig({ experimental: { - svgo: true + svgOptimizer: svgoOptimizer() } -}) +}); ``` ## Usage -No change to using SVG components is required to take advantage of this feature. With experimental `svgo` enabled, all your SVG component import files will be automatically optimized: +No change to using SVG components is required to take advantage of this feature. With experimental SVG optimization enabled, all your SVG component import files will be automatically optimized: ```astro title="src/pages/index.astro" --- @@ -46,32 +46,36 @@ The SVG will be optimized during the build process, resulting in smaller file si Note that this optimization applies to every SVG component import in your project. It is not possible to opt out on a per-component basis. -## Configuration +## SVGO -You can pass an [SVGO configuration object](https://github.com/svg/svgo#configuration) to customize optimization behavior: +Astro provides one built-in optimizer using [SVGO](https://svgo.dev/): -```js title="astro.config.mjs" -export default defineConfig({ - experimental: { - svgo: { - multipass: true, - floatPrecision: 2, - plugins: [ - 'preset-default', - 'removeXMLNS', - { - name: "removeXlink", - params: { - includeLegacy: true - } - } - ] +```js +import { svgoOptimizer } from "astro/config" +``` + +### Configuration + +You can pass an object containing [SVGO configuration options](https://github.com/svg/svgo#configuration) to customize optimization behavior: + +```js +svgoOptimizer({ + multipass: true, + floatPrecision: 2, + plugins: [ + 'preset-default', + 'removeXMLNS', + { + name: "removeXlink", + params: { + includeLegacy: true + } } - } -}) + ] +}); ``` -### `plugins` +#### `plugins` **Type:** `Array`
**Default:** `[]` @@ -82,55 +86,47 @@ This can include SVGO's [`preset-default`](https://svgo.dev/docs/preset-default/ To use a plugin’s default configuration, add its name to the array. If you need more control, use the `overrides` parameter to customize specific plugins within `preset-default`, or pass an object with a plugin's `name` to override its individual parameters. -```js title="astro.config.mjs" -export default defineConfig({ - experimental: { - svgo: { - plugins: [ - { - name: 'preset-default', - params: { - overrides: { - convertPathData: false, - convertTransform: { - degPrecision: 1, - transformPrecision: 3 - }, - inlineStyles: false - }, +```js +svgoOptimizer({ + plugins: [ + { + name: 'preset-default', + params: { + overrides: { + convertPathData: false, + convertTransform: { + degPrecision: 1, + transformPrecision: 3 }, + inlineStyles: false }, - 'removeXMLNS', - { - name: "removeXlink", - params: { - includeLegacy: true - } - } - ] + }, + }, + 'removeXMLNS', + { + name: "removeXlink", + params: { + includeLegacy: true + } } - } -}) + ] +}); ``` -### Other configuration options +#### Other configuration options There are a few [SVGO configuration options](https://github.com/svg/svgo/blob/66d503a48c6c95661726262a3068053c429b06a9/lib/types.ts#L335), especially `floatPrecision` and `multipass`, that can be passed directly to your config object: -```js title="astro.config.mjs" -export default defineConfig({ - experimental: { - svgo: { - multipass: true, - floatPrecision: 2 - } - } -}) +```js +svgoOptimizer({ + multipass: true, + floatPrecision: 2, +}); ``` The `multipass` option sets whether to run the optimization engine multiple times until no further optimizations are found. The `floatPrecision` option sets the number of decimal places to preserve globally, but can be overridden for a specific plugin by specifying a custom value in its `params` property. -## Common use cases +### Common use cases SVGO provides an extensive [default plugin list](https://svgo.dev/docs/preset-default/) with opinionated optimizations. While using this preset is more convenient than adding each plugin individually, you may need to customize it further. For example, it may remove items or clean up too aggressively for your situation, especially when using animations. @@ -138,76 +134,103 @@ SVGO provides an extensive [default plugin list](https://svgo.dev/docs/preset-de You may want to preserve certain SVG attributes and elements, such as `