astro-webmanifest
This Astro integration generates a web application manifest, favicon, icons and inserts appropriate html to <head>
section for your Astro project during build.
The web app manifest provides information about a Progressive Web App (PWA) in a JSON text file. See Google's advice on web app manifest to learn more. Current standard for the manifest is on W3C. See also on MDN.
Why astro-webmanifest?
This integration provides numerous features beyond manifest configuration to make your life easier, they are:
- automatic icon generation - generates multiple icon sizes from a single source;
- favicon support;
- inserts all required
link
s andmeta
to<head>
section of generated pages; - legacy icon support (iOS);
- localization - provides unique manifests for path-based localization.
Each of these features has extensive configuration available so you are always in control.
See usage in the demo repos: basic, advanced and i18n.
Installation
There are two main ways to add astro-webmanifest integration to your Astro project.
Astro CLI tool
You should run astro add
command in your project directory. This command after prompt will install required dependencies and apply changes to astro.config.*.
# Using NPM
npx astro add astro-webmanifest
# Using Yarn
yarn astro add astro-webmanifest
# Using PNPM
pnpx astro add astro-webmanifest
If you run into any hiccups, feel free to log an issue on my GitHub.
Install dependencies manually
First, install the astro-webmanifest integration like so:
# Using NPM
npm install --save-dev astro-webmanifest
# Using Yarn
yarn add -D astro-webmanifest
# Using PNPM
pnpm add -D astro-webmanifest
Then apply this integration to your astro.config.*. All details below in Getting started.
Getting started
The astro-webmanifest
requires the options parameter to configure the integration.
experimental
property to your astro.config.*, because only official @astrojs/* integrations are currently supported by Astro. Set the experimental.integrations
value to true
.
Then, apply this integration to your astro.config.* by using the integrations
property.
The sample configuration is below:
astro.config.mjs
// astro.config.mjs
import { defineConfig } from 'astro/config';
import webmanifest from 'astro-webmanifest';
export default defineConfig({
// ...
// Important!
// Only official '@astrojs/*' integrations are currently supported by Astro.
// Add 'experimental.integrations: true' to make 'astro-webmanifest' working
// with 'astro build' command.
experimental: {
integrations: true,
},
integrations: [
webmanifest({
icon: 'src/images/your-icon.svg', // source for favicon & icons
name: 'Your App name', // required
short_name: 'App',
description: 'Here is your app description',
start_url: '/',
theme_color: '#3367D6',
background_color: '#3367D6',
display: 'standalone',
}),
],
});
Next put a source file for icons generation to the src/images
folder.
Now, build your site for production via the astro build
command. You should find your web manifest, all icons, favicons under dist/
folder!
The manifest.webmanifest's content will be:
{
"name": "Your App name",
"icons": [
{
"src": "icons/icon-48x48.png",
"sizes": "48x48",
"type": "image/png"
},
{
"src": "icons/icon-72x72.png",
"sizes": "72x72",
"type": "image/png"
},
{
"src": "icons/icon-96x96.png",
"sizes": "96x96",
"type": "image/png"
},
{
"src": "icons/icon-144x144.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src": "icons/icon-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "icons/icon-256x256.png",
"sizes": "256x256",
"type": "image/png"
},
{
"src": "icons/icon-384x384.png",
"sizes": "384x384",
"type": "image/png"
},
{
"src": "icons/icon-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"short_name": "App",
"description": "Here is your app description",
"start_url": "/",
"theme_color": "#3367D6",
"background_color": "#3367D6",
"display": "standalone"
}
The integration inserts into <head>
section of every generated page the following html tags:
<link rel="icon" href="/favicon-32x32.png" type="image/png" />
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
<meta name="theme-color" content="#3367D6" />
<link rel="manifest" href="/manifest.webmanifest" crossorigin="anonymous" />
You can also check Astro Integration Documentation for more on integrations.
Generations modes
There are 3 usage modes of astro-webmanifest
integration: auto, hybrid and manual.
Automatic mode
For the most users - you need only the icon
option to generate all required icons and favicons.
The integration has default icon preset to generate all icons.
icon: 'src/images/your-icon.svg',
...
Hybrid mode
Additionally to the icon
option you need to provide the icons
array as a template to generate required icons.
No default icons. Only icons from the array will be created.
icon: 'src/images/your-icon.svg',
icons: [
{
src: 'icons/icon-96x96.png',
sizes: '96x96',
type: 'image/png',
},
{
src: 'icons/icon-256x256.png',
sizes: '256x256',
type: 'image/png',
},
// add any other icon sizes
],
...
Manual mode
If you don't provide icon
option, you will be fully responsible for manifest configuration.
You should create all icons and favicons manually and put them to the public
folder.
icons: [
{
src: 'icons/icon-96x96.png',
sizes: '96x96',
type: 'image/png',
},
{
src: 'icons/icon-256x256.png',
sizes: '256x256',
type: 'image/png',
},
// add any other icons
],
...
sizes
property has value any
or contains more then one size (96x96 128x128
) in that case such entry will be excluded from automatic generation.
Options
Name | Type | Required | Default | Description |
---|---|---|---|---|
icon |
String |
No | This is a source for automatically generated favicon and icons. It's a part of Webmanifest type.Format: JPEG, PNG, WebP, TIFF, GIF or SVG Size: at least as big as the largest icon being generated (512x512 by default). Form: preferably square, otherwise the results will be padded with transparent bars to be square. If the icon is empty - no automatic icon generation. |
|
config |
No | |||
- iconPurpose
|
IconPurpose[] |
No | Array of badge |maskable |any |monochrome .If provided it will be appended to the purpose property of generated icons. |
|
- createFavicon
|
Boolean |
No | true |
Enable (if icon is not empty) or disable a favicon generation |
- insertFaviconLinks
|
Boolean |
No | true |
Enable (if icon is not empty) or disable a favicon links in <head>
|
- insertThemeColorMeta
|
Boolean |
No | true |
Enable (if theme_color is not empty) or disable meta in <head>
|
- insertManifestLink
|
Boolean |
No | true |
Enable or disable a manifest link in <head>
|
- crossOrigin
|
anonymous |use-credentials
|
No | anonymus |
crossorigin attribute for the manifest link in <head> . More details on MDN
|
- insertAppleTouchLinks
|
Boolean |
No | false |
Enable or disable apple-touch-icon links in <head> .iOS versions before 11.3 don't have support for web app manifest spec and don't recognize the icons defined in the webmanifest, so the creation of apple-touch-icon links in <head> is needed. |
- indent
|
String |
No | 4 spaces | Leading characters for every line in <head> to make output more readable. |
- eol
|
String |
No | \n |
Trailing characters for every line in <head> to make output more readable.Set it to "" to save few bytes on html output. |
- outfile
|
String |
No | manifest.webmanifest |
Template name for generated manifest file. |
locales |
Locales |
No |
Record<string, Webmanifest> - key/object pairs. See usage in Localization section. |
<head>
sections. It could impact on a build time for large sites.
Webmanifest
Name | Type | Required | Description |
---|---|---|---|
icon |
String |
No | See usage in Generation modes section. |
icons |
Icon[] |
No | See usage in Generation modes section. |
name |
String |
Yes | You must provide the name of your app. |
short_name |
String |
No | |
description |
String |
No | |
categories |
String[] |
No | |
lang |
String |
No | |
dir |
Dir |
No |
auto |ltr |rtl
|
iarc_rating_id |
String |
No | |
id |
String |
No | |
start_url |
String |
No | |
scope |
String |
No | |
theme_color |
String |
No | Source for meta in <head>
|
background_color |
String |
No | |
display |
Display |
No |
fullscreen |standalone |minimal-ui |browser
|
display_override |
Display[] |
No | |
orientation |
Orientation |
No |
any |natural |landscape |landscape-primary |landscape-secondary |portrait |portrait-primary |portrait-secondary
|
protocol_handlers |
ProtocolHandler[] |
No | |
prefer_related_applications |
Boolean |
No | |
related_applications |
RelatedApplication[] |
No | |
screenshots |
Image[] |
No | |
shortcuts |
Shortcut[] |
No |
Icon
Name | Type | Required | Description |
---|---|---|---|
src |
String |
Yes | The path to the image file in URL form. |
sizes |
String |
No | Space-separated image dimensions. Syntax on MDN |
type |
String |
No | Media type of the image |
purpose |
String |
No | Space separated list of image purposes (IconPurpose type). See on W3C
|
For Image
, Shortcut
, RelatedApplication
, ProtocolHandler
look on content of index.ts.
Also you can find detailed descriptions on W3C and MDN.
Demo with advanced configuration is in this repo.
Localization
Localization allows you to create a unique manifest, icon set and <head>
html for each individual language.
You need to provide locales
property as a Record<string, Webmanifest>
.
The integration uses keys of locales
property to make a manifest name unique and to determine a page language by path.
The integration expects page paths in the following format: /{locale}{path}, where the locale is a key from locales
property.
Sample configuration below:
...
icon: 'src/images/logomark-light.svg',
name: 'Webmanifest i18n test',
short_name: 'Test',
description: 'This is the application description',
lang: 'en-US',
start_url: '/',
theme_color: '#3367D6',
background_color: '#3367D6',
display: 'standalone',
locales: {
es: {
name: 'Prueba Webmanifest i18n',
short_name: 'Prueba',
description: 'Esta es la descripción de la aplicación.',
lang: 'es-ES',
start_url: '/es',
},
fr: {
name: 'Test i18n du manifeste Web',
short_name: 'Test',
description: "Ceci est la description de l'application",
lang: 'fr-CA',
start_url: '/fr',
},
},
...
By this configuration three separate manifests will be generated:
-
manifest.webmanifest
- for default language; -
manifest-fr.webmanifest
- forfr
language; -
manifest-es.webmanifest
- fores
language.
And language specific html will be inserted to <head>
section of generated pages.
If you need a separate set of icons for each language add icon
property.
...
icon: 'src/images/logo.svg',
lang: 'en-US',
...
locales: {
es: {
icon: 'src/images/logo-es.svg',
lang: 'es-ES',
...
},
fr: {
lang: 'fr-CA',
...
},
},
...
In this configuration the default en
language and the fr
language will have common icon set, es
- own icon set.
You could explore a localization usage in this demo repo.
Using Configuration Files
You could configure the integration with external file webmanifest.config.*
(js
, cjs
, mjs
). Put it to the application root
folder (see about root
in official docs).
The external config must contain a default export statement:
// ESM
export default {
...
};
or
// CommonJS
module.exports = {
...
};
How does the integration internally resolve a config?
Options parameter provided? | External config exists? | Result |
---|---|---|
No | No | Throw error |
Yes | No | Options parameter used |
No | Yes | External config used |
Yes | Yes | External config is merged with options parameter |
The external configuration usage example is in this demo repo.
There are two possibilities to make astro-webmanifest integration working with current version of Astro.
Set the experimental.integrations
option to true
in your astro.config.*.
// astro.config.mjs
export default defineConfig({
// ...
experimental: {
integrations: true,
},
});
Or use the --experimental-integrations
flag for build command.
astro build --experimental-integrations