@mannisto/astro-metadata 1.0.0-alpha.2 → 1.0.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +78 -65
- package/index.ts +1 -2
- package/package.json +1 -1
- package/src/components/Favicon.astro +54 -151
- package/src/components/Head.astro +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Astro Metadata
|
|
2
2
|
|
|
3
|
-

|
|
4
4
|
|
|
5
5
|

|
|
6
6
|

|
|
@@ -8,15 +8,13 @@
|
|
|
8
8
|
|
|
9
9
|
Astro components for managing your page head — metadata, social sharing, favicons, and SEO.
|
|
10
10
|
|
|
11
|
-
---
|
|
12
|
-
|
|
13
11
|
## Table of contents
|
|
14
12
|
|
|
15
13
|
- [Installation](#installation)
|
|
16
|
-
- [
|
|
17
|
-
- [
|
|
18
|
-
- [
|
|
19
|
-
- [
|
|
14
|
+
- [Usage](#usage)
|
|
15
|
+
- [Head component](#1-head-component)
|
|
16
|
+
- [Individual components](#2-individual-components)
|
|
17
|
+
- [Metadata utility](#3-metadata-utility)
|
|
20
18
|
- [Components](#components)
|
|
21
19
|
- [Canonical](#canonical)
|
|
22
20
|
- [Description](#description)
|
|
@@ -31,16 +29,19 @@ Astro components for managing your page head — metadata, social sharing, favic
|
|
|
31
29
|
- [Twitter](#twitter)
|
|
32
30
|
- [License](#license)
|
|
33
31
|
|
|
34
|
-
---
|
|
35
|
-
|
|
36
32
|
## Installation
|
|
37
33
|
```bash
|
|
34
|
+
# pnpm
|
|
38
35
|
pnpm add @mannisto/astro-metadata
|
|
39
|
-
```
|
|
40
36
|
|
|
41
|
-
|
|
37
|
+
# npm
|
|
38
|
+
npm install @mannisto/astro-metadata
|
|
39
|
+
|
|
40
|
+
# yarn
|
|
41
|
+
yarn add @mannisto/astro-metadata
|
|
42
|
+
```
|
|
42
43
|
|
|
43
|
-
##
|
|
44
|
+
## Usage
|
|
44
45
|
|
|
45
46
|
There are three ways to use this package. Pick what suits your project, or combine them freely.
|
|
46
47
|
|
|
@@ -110,12 +111,10 @@ import { Title, Description, OpenGraph, Favicon } from "@mannisto/astro-metadata
|
|
|
110
111
|
}}
|
|
111
112
|
/>
|
|
112
113
|
<Favicon
|
|
113
|
-
icons={
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
},
|
|
118
|
-
}}
|
|
114
|
+
icons={[
|
|
115
|
+
{ path: "/favicon.ico" },
|
|
116
|
+
{ path: "/favicon.svg" },
|
|
117
|
+
]}
|
|
119
118
|
/>
|
|
120
119
|
</head>
|
|
121
120
|
<body>
|
|
@@ -181,7 +180,8 @@ Best for sites with deeply nested layouts, or when you want to keep metadata co-
|
|
|
181
180
|
|
|
182
181
|
## Components
|
|
183
182
|
|
|
184
|
-
|
|
183
|
+
<details>
|
|
184
|
+
<summary><strong>Canonical</strong></summary>
|
|
185
185
|
|
|
186
186
|
Renders a canonical link tag. Falls back to `Astro.url.href` when no value is provided, so every page gets a canonical tag with zero configuration.
|
|
187
187
|
```astro
|
|
@@ -192,9 +192,12 @@ Renders a canonical link tag. Falls back to `Astro.url.href` when no value is pr
|
|
|
192
192
|
|------|------|-------------|
|
|
193
193
|
| `value` | `string` | Canonical URL. Defaults to `Astro.url.href`. |
|
|
194
194
|
|
|
195
|
+
</details>
|
|
196
|
+
|
|
195
197
|
---
|
|
196
198
|
|
|
197
|
-
|
|
199
|
+
<details>
|
|
200
|
+
<summary><strong>Description</strong></summary>
|
|
198
201
|
```astro
|
|
199
202
|
<Description value="Welcome to my site" />
|
|
200
203
|
```
|
|
@@ -203,59 +206,48 @@ Renders a canonical link tag. Falls back to `Astro.url.href` when no value is pr
|
|
|
203
206
|
|------|------|-------------|
|
|
204
207
|
| `value` | `string` | Page description |
|
|
205
208
|
|
|
209
|
+
</details>
|
|
210
|
+
|
|
206
211
|
---
|
|
207
212
|
|
|
208
|
-
|
|
213
|
+
<details>
|
|
214
|
+
<summary><strong>Favicon</strong></summary>
|
|
209
215
|
|
|
210
|
-
Favicon support with
|
|
216
|
+
Favicon support with light and dark mode variants and automatic MIME type detection.
|
|
211
217
|
```astro
|
|
212
218
|
<Favicon
|
|
213
|
-
icons={
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
},
|
|
220
|
-
|
|
221
|
-
svg: { path: "/favicon-light.svg" },
|
|
222
|
-
},
|
|
223
|
-
darkMode: {
|
|
224
|
-
svg: { path: "/favicon-dark.svg" },
|
|
225
|
-
},
|
|
226
|
-
}}
|
|
219
|
+
icons={[
|
|
220
|
+
{ path: "/favicon.ico" },
|
|
221
|
+
{ path: "/favicon.svg" },
|
|
222
|
+
{ path: "/favicon-96x96.png", size: 96 },
|
|
223
|
+
{ path: "/apple-touch-icon.png", size: 180, apple: true },
|
|
224
|
+
{ path: "/favicon-dark.svg", theme: "dark" },
|
|
225
|
+
{ path: "/favicon-light.svg", theme: "light" },
|
|
226
|
+
]}
|
|
227
227
|
manifest="/site.webmanifest"
|
|
228
|
-
cacheBust
|
|
229
228
|
/>
|
|
230
229
|
```
|
|
231
230
|
|
|
232
231
|
| Prop | Type | Description |
|
|
233
232
|
|------|------|-------------|
|
|
234
|
-
| `icons
|
|
235
|
-
| `icons.lightMode` | `FaviconIcons` | Favicons shown in light color scheme |
|
|
236
|
-
| `icons.darkMode` | `FaviconIcons` | Favicons shown in dark color scheme |
|
|
233
|
+
| `icons` | `FaviconFile[]` | List of favicon files |
|
|
237
234
|
| `manifest` | `string` | Path to web app manifest |
|
|
238
|
-
| `cacheBust` | `boolean` | Append `?v={timestamp}` to favicon URLs |
|
|
239
|
-
|
|
240
|
-
#### FaviconIcons
|
|
241
|
-
|
|
242
|
-
| Prop | Type | Description |
|
|
243
|
-
|------|------|-------------|
|
|
244
|
-
| `ico` | `FaviconFile` | `.ico` favicon |
|
|
245
|
-
| `svg` | `FaviconFile` | `.svg` favicon |
|
|
246
|
-
| `png` | `FaviconFile \| FaviconFile[]` | One or more `.png` favicons |
|
|
247
|
-
| `apple` | `FaviconFile` | Apple touch icon |
|
|
248
235
|
|
|
249
236
|
#### FaviconFile
|
|
250
237
|
|
|
251
238
|
| Prop | Type | Description |
|
|
252
239
|
|------|------|-------------|
|
|
253
|
-
| `path` | `string` | Path to the file |
|
|
240
|
+
| `path` | `string` | Path to the file. MIME type is detected automatically. |
|
|
254
241
|
| `size` | `number` | Size in pixels. Rendered as `NxN` in the `sizes` attribute. |
|
|
242
|
+
| `theme` | `"light" \| "dark"` | Adds a `prefers-color-scheme` media query |
|
|
243
|
+
| `apple` | `boolean` | Renders as `<link rel="apple-touch-icon">` |
|
|
244
|
+
|
|
245
|
+
</details>
|
|
255
246
|
|
|
256
247
|
---
|
|
257
248
|
|
|
258
|
-
|
|
249
|
+
<details>
|
|
250
|
+
<summary><strong>Head</strong></summary>
|
|
259
251
|
|
|
260
252
|
Wraps the entire page head and composes all sub-components internally. Charset and viewport are always included and can be overridden if needed.
|
|
261
253
|
```astro
|
|
@@ -272,11 +264,10 @@ Wraps the entire page head and composes all sub-components internally. Charset a
|
|
|
272
264
|
},
|
|
273
265
|
}}
|
|
274
266
|
favicon={{
|
|
275
|
-
icons:
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
},
|
|
267
|
+
icons: [
|
|
268
|
+
{ path: "/favicon.ico" },
|
|
269
|
+
{ path: "/favicon.svg" },
|
|
270
|
+
],
|
|
280
271
|
}}
|
|
281
272
|
/>
|
|
282
273
|
```
|
|
@@ -308,9 +299,12 @@ Wraps the entire page head and composes all sub-components internally. Charset a
|
|
|
308
299
|
</Head>
|
|
309
300
|
```
|
|
310
301
|
|
|
302
|
+
</details>
|
|
303
|
+
|
|
311
304
|
---
|
|
312
305
|
|
|
313
|
-
|
|
306
|
+
<details>
|
|
307
|
+
<summary><strong>Keywords</strong></summary>
|
|
314
308
|
```astro
|
|
315
309
|
<Keywords value={["astro", "seo", "metadata"]} />
|
|
316
310
|
```
|
|
@@ -319,9 +313,12 @@ Wraps the entire page head and composes all sub-components internally. Charset a
|
|
|
319
313
|
|------|------|-------------|
|
|
320
314
|
| `value` | `string[]` | List of keywords |
|
|
321
315
|
|
|
316
|
+
</details>
|
|
317
|
+
|
|
322
318
|
---
|
|
323
319
|
|
|
324
|
-
|
|
320
|
+
<details>
|
|
321
|
+
<summary><strong>LanguageAlternates</strong></summary>
|
|
325
322
|
|
|
326
323
|
Renders `<link rel="alternate" hreflang>` tags for multilingual sites. Tells search engines which language version to serve for a given region.
|
|
327
324
|
```astro
|
|
@@ -340,9 +337,12 @@ Renders `<link rel="alternate" hreflang>` tags for multilingual sites. Tells sea
|
|
|
340
337
|
| `alternates[].href` | `string` | Full URL of the alternate page |
|
|
341
338
|
| `alternates[].hreflang` | `string` | Language or region code, e.g. `en`, `fi`, `en-US`, `x-default` |
|
|
342
339
|
|
|
340
|
+
</details>
|
|
341
|
+
|
|
343
342
|
---
|
|
344
343
|
|
|
345
|
-
|
|
344
|
+
<details>
|
|
345
|
+
<summary><strong>OpenGraph</strong></summary>
|
|
346
346
|
|
|
347
347
|
Renders Open Graph meta tags for rich previews when your pages are shared on social platforms. When used inside `Head`, `title`, `description` and `url` fall back to the page values automatically.
|
|
348
348
|
```astro
|
|
@@ -374,9 +374,12 @@ Renders Open Graph meta tags for rich previews when your pages are shared on soc
|
|
|
374
374
|
| `siteName` | `string` | — | Name of the site |
|
|
375
375
|
| `locale` | `string` | — | Locale, e.g. `en_US` |
|
|
376
376
|
|
|
377
|
+
</details>
|
|
378
|
+
|
|
377
379
|
---
|
|
378
380
|
|
|
379
|
-
|
|
381
|
+
<details>
|
|
382
|
+
<summary><strong>Robots</strong></summary>
|
|
380
383
|
|
|
381
384
|
Controls how search engines crawl and index your page. Defaults to `index, follow`.
|
|
382
385
|
```astro
|
|
@@ -394,9 +397,12 @@ Controls how search engines crawl and index your page. Defaults to `index, follo
|
|
|
394
397
|
| `noSnippet` | `boolean` | — | Prevent text snippets in search results |
|
|
395
398
|
| `extra` | `string` | — | Additional directives, e.g. `"max-snippet:-1, max-image-preview:large"` |
|
|
396
399
|
|
|
400
|
+
</details>
|
|
401
|
+
|
|
397
402
|
---
|
|
398
403
|
|
|
399
|
-
|
|
404
|
+
<details>
|
|
405
|
+
<summary><strong>Schema</strong></summary>
|
|
400
406
|
|
|
401
407
|
Outputs a `<script type="application/ld+json">` tag for structured data. Use it to help search engines understand your content and qualify for rich results.
|
|
402
408
|
```astro
|
|
@@ -414,14 +420,16 @@ Outputs a `<script type="application/ld+json">` tag for structured data. Use it
|
|
|
414
420
|
|------|------|-------------|
|
|
415
421
|
| `schema` | `Record<string, unknown>` | JSON-LD object |
|
|
416
422
|
|
|
423
|
+
</details>
|
|
424
|
+
|
|
417
425
|
---
|
|
418
426
|
|
|
419
|
-
|
|
427
|
+
<details>
|
|
428
|
+
<summary><strong>Title</strong></summary>
|
|
420
429
|
|
|
421
430
|
Renders the `<title>` tag. The template must contain `%s`, which is replaced with the page title — TypeScript enforces this at the type level.
|
|
422
431
|
```astro
|
|
423
432
|
<Title value="My Page" template="%s | My Site" />
|
|
424
|
-
<!-- <title>My Page | My Site</title> -->
|
|
425
433
|
```
|
|
426
434
|
|
|
427
435
|
| Prop | Type | Description |
|
|
@@ -429,9 +437,12 @@ Renders the `<title>` tag. The template must contain `%s`, which is replaced wit
|
|
|
429
437
|
| `value` | `string` | Page title. Required. |
|
|
430
438
|
| `template` | `` `${string}%s${string}` `` | Template string. Must contain `%s`. |
|
|
431
439
|
|
|
440
|
+
</details>
|
|
441
|
+
|
|
432
442
|
---
|
|
433
443
|
|
|
434
|
-
|
|
444
|
+
<details>
|
|
445
|
+
<summary><strong>Twitter</strong></summary>
|
|
435
446
|
|
|
436
447
|
Renders Twitter card meta tags for rich previews on X. When used inside `Head`, `title` and `description` fall back to the page values automatically.
|
|
437
448
|
```astro
|
|
@@ -456,6 +467,8 @@ Renders Twitter card meta tags for rich previews on X. When used inside `Head`,
|
|
|
456
467
|
| `site` | `string` | — | Twitter handle of the site, e.g. `@mysite` |
|
|
457
468
|
| `creator` | `string` | — | Twitter handle of the content author |
|
|
458
469
|
|
|
470
|
+
</details>
|
|
471
|
+
|
|
459
472
|
---
|
|
460
473
|
|
|
461
474
|
## License
|
package/index.ts
CHANGED
|
@@ -20,8 +20,7 @@ export type { Props as RobotsProps } from "./src/components/Robots.a
|
|
|
20
20
|
export type { Props as OpenGraphProps } from "./src/components/OpenGraph.astro"
|
|
21
21
|
export type { Props as TwitterProps } from "./src/components/Twitter.astro"
|
|
22
22
|
export type { Props as FaviconProps,
|
|
23
|
-
FaviconFile
|
|
24
|
-
FaviconIcons } from "./src/components/Favicon.astro"
|
|
23
|
+
FaviconFile } from "./src/components/Favicon.astro"
|
|
25
24
|
export type { Props as SchemaProps } from "./src/components/Schema.astro"
|
|
26
25
|
export type { Props as LanguageAlternatesProps,
|
|
27
26
|
LanguageAlternate } from "./src/components/LanguageAlternates.astro"
|
package/package.json
CHANGED
|
@@ -1,177 +1,80 @@
|
|
|
1
1
|
---
|
|
2
2
|
|
|
3
3
|
export type FaviconFile = {
|
|
4
|
-
path
|
|
5
|
-
size?
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export type FaviconIcons = {
|
|
9
|
-
ico? : FaviconFile
|
|
10
|
-
png? : FaviconFile | FaviconFile[]
|
|
11
|
-
svg? : FaviconFile
|
|
12
|
-
apple? : FaviconFile
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
type PreparedFile = {
|
|
16
|
-
path : string
|
|
17
|
-
size? : string
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
type PreparedIcons = {
|
|
21
|
-
ico? : PreparedFile
|
|
22
|
-
png? : PreparedFile[]
|
|
23
|
-
svg? : PreparedFile
|
|
24
|
-
apple? : PreparedFile
|
|
4
|
+
path : string
|
|
5
|
+
size? : number
|
|
6
|
+
theme? : "light" | "dark"
|
|
7
|
+
apple? : boolean
|
|
25
8
|
}
|
|
26
9
|
|
|
27
10
|
export type Props = {
|
|
28
|
-
icons:
|
|
29
|
-
|
|
30
|
-
lightMode? : FaviconIcons
|
|
31
|
-
darkMode? : FaviconIcons
|
|
32
|
-
}
|
|
33
|
-
manifest? : string
|
|
34
|
-
cacheBust? : boolean
|
|
11
|
+
icons : FaviconFile[]
|
|
12
|
+
manifest? : string
|
|
35
13
|
}
|
|
36
14
|
|
|
37
|
-
const {
|
|
38
|
-
icons,
|
|
39
|
-
manifest
|
|
40
|
-
cacheBust = false
|
|
15
|
+
const {
|
|
16
|
+
icons,
|
|
17
|
+
manifest
|
|
41
18
|
} = Astro.props
|
|
42
19
|
|
|
43
|
-
const cacheBustString = cacheBust
|
|
44
|
-
? `?v=${Date.now()}`
|
|
45
|
-
: ""
|
|
46
|
-
|
|
47
20
|
/**
|
|
48
|
-
*
|
|
49
|
-
* and converting the numeric size to the "NxN" format browsers expect.
|
|
21
|
+
* Detects the MIME type of a favicon file from its extension.
|
|
50
22
|
*
|
|
51
|
-
* @param
|
|
52
|
-
* @returns The
|
|
23
|
+
* @param path - The path to the favicon file.
|
|
24
|
+
* @returns The MIME type of the file.
|
|
53
25
|
*/
|
|
54
|
-
function
|
|
55
|
-
if (
|
|
56
|
-
return
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
26
|
+
function getMimeType(path: string): string {
|
|
27
|
+
if (path.endsWith(".svg")) return "image/svg+xml"
|
|
28
|
+
if (path.endsWith(".png")) return "image/png"
|
|
29
|
+
if (path.endsWith(".webp")) return "image/webp"
|
|
30
|
+
if (path.endsWith(".jpg") ||
|
|
31
|
+
path.endsWith(".jpeg")) return "image/jpeg"
|
|
32
|
+
if (path.endsWith(".ico")) return "image/x-icon"
|
|
33
|
+
return "image/x-icon"
|
|
60
34
|
}
|
|
61
35
|
|
|
62
36
|
/**
|
|
63
|
-
*
|
|
64
|
-
* Normalizes the png field to always be an array for consistent rendering.
|
|
37
|
+
* Builds the media query string for a given theme.
|
|
65
38
|
*
|
|
66
|
-
* @param
|
|
67
|
-
* @returns The
|
|
39
|
+
* @param theme - The theme to build the media query for.
|
|
40
|
+
* @returns The media query string, or undefined if no theme was provided.
|
|
68
41
|
*/
|
|
69
|
-
function
|
|
70
|
-
if (
|
|
71
|
-
return
|
|
72
|
-
|
|
73
|
-
svg: prepareFile(set.svg),
|
|
74
|
-
apple: prepareFile(set.apple),
|
|
75
|
-
png: set.png
|
|
76
|
-
? (Array.isArray(set.png) ? set.png : [set.png]).map((file) => prepareFile(file)!)
|
|
77
|
-
: undefined,
|
|
78
|
-
}
|
|
42
|
+
function getMedia(theme?: "light" | "dark"): string | undefined {
|
|
43
|
+
if (theme === "light") return "(prefers-color-scheme: light)"
|
|
44
|
+
if (theme === "dark") return "(prefers-color-scheme: dark)"
|
|
45
|
+
return undefined
|
|
79
46
|
}
|
|
80
47
|
|
|
81
|
-
const prepared = {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
48
|
+
const prepared = icons.map((file) => ({
|
|
49
|
+
path : file.path,
|
|
50
|
+
size : file.size ? `${file.size}x${file.size}` : undefined,
|
|
51
|
+
type : getMimeType(file.path),
|
|
52
|
+
media : getMedia(file.theme),
|
|
53
|
+
apple : file.apple ?? false,
|
|
54
|
+
}))
|
|
86
55
|
|
|
87
56
|
---
|
|
88
57
|
|
|
89
58
|
{manifest && <link rel="manifest" href={manifest} />}
|
|
90
59
|
|
|
91
|
-
{prepared.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
rel="icon"
|
|
102
|
-
type="image/svg+xml"
|
|
103
|
-
href={prepared.default.svg.path}
|
|
104
|
-
sizes={prepared.default.svg.size}
|
|
105
|
-
/>
|
|
106
|
-
)}
|
|
107
|
-
{prepared.default?.apple && (
|
|
108
|
-
<link
|
|
109
|
-
rel="apple-touch-icon"
|
|
110
|
-
href={prepared.default.apple.path}
|
|
111
|
-
sizes={prepared.default.apple.size}
|
|
112
|
-
/>
|
|
113
|
-
)}
|
|
114
|
-
{prepared.default?.png?.map((png) => (
|
|
115
|
-
<link
|
|
116
|
-
rel="icon"
|
|
117
|
-
type="image/png"
|
|
118
|
-
href={png.path}
|
|
119
|
-
sizes={png.size}
|
|
120
|
-
/>
|
|
121
|
-
))}
|
|
122
|
-
|
|
123
|
-
{prepared.lightMode?.ico && (
|
|
124
|
-
<link
|
|
125
|
-
rel="icon"
|
|
126
|
-
type="image/x-icon"
|
|
127
|
-
href={prepared.lightMode.ico.path}
|
|
128
|
-
sizes={prepared.lightMode.ico.size}
|
|
129
|
-
media="(prefers-color-scheme: light)"
|
|
130
|
-
/>
|
|
131
|
-
)}
|
|
132
|
-
{prepared.lightMode?.svg && (
|
|
133
|
-
<link
|
|
134
|
-
rel="icon"
|
|
135
|
-
type="image/svg+xml"
|
|
136
|
-
href={prepared.lightMode.svg.path}
|
|
137
|
-
sizes={prepared.lightMode.svg.size}
|
|
138
|
-
media="(prefers-color-scheme: light)"
|
|
139
|
-
/>
|
|
140
|
-
)}
|
|
141
|
-
{prepared.lightMode?.png?.map((png) => (
|
|
142
|
-
<link
|
|
143
|
-
rel="icon"
|
|
144
|
-
type="image/png"
|
|
145
|
-
href={png.path}
|
|
146
|
-
sizes={png.size}
|
|
147
|
-
media="(prefers-color-scheme: light)"
|
|
148
|
-
/>
|
|
149
|
-
))}
|
|
60
|
+
{prepared.map((icon) => {
|
|
61
|
+
if (icon.apple) {
|
|
62
|
+
return (
|
|
63
|
+
<link
|
|
64
|
+
rel="apple-touch-icon"
|
|
65
|
+
href={icon.path}
|
|
66
|
+
sizes={icon.size}
|
|
67
|
+
/>
|
|
68
|
+
)
|
|
69
|
+
}
|
|
150
70
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
)
|
|
160
|
-
|
|
161
|
-
<link
|
|
162
|
-
rel="icon"
|
|
163
|
-
type="image/svg+xml"
|
|
164
|
-
href={prepared.darkMode.svg.path}
|
|
165
|
-
sizes={prepared.darkMode.svg.size}
|
|
166
|
-
media="(prefers-color-scheme: dark)"
|
|
167
|
-
/>
|
|
168
|
-
)}
|
|
169
|
-
{prepared.darkMode?.png?.map((png) => (
|
|
170
|
-
<link
|
|
171
|
-
rel="icon"
|
|
172
|
-
type="image/png"
|
|
173
|
-
href={png.path}
|
|
174
|
-
sizes={png.size}
|
|
175
|
-
media="(prefers-color-scheme: dark)"
|
|
176
|
-
/>
|
|
177
|
-
))}
|
|
71
|
+
return (
|
|
72
|
+
<link
|
|
73
|
+
rel="icon"
|
|
74
|
+
type={icon.type}
|
|
75
|
+
href={icon.path}
|
|
76
|
+
sizes={icon.size}
|
|
77
|
+
media={icon.media}
|
|
78
|
+
/>
|
|
79
|
+
)
|
|
80
|
+
})}
|