vite-plugin-sitemap-ts 1.1.3 → 1.3.0
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 +82 -5
- package/dist/index.cjs +20 -5
- package/dist/index.d.cts +20 -3
- package/dist/index.d.ts +20 -3
- package/dist/index.js +20 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -41,6 +41,7 @@ sitemap({
|
|
|
41
41
|
hostname: 'https://example.com',
|
|
42
42
|
})
|
|
43
43
|
```
|
|
44
|
+
|
|
44
45
|
*Output:*
|
|
45
46
|
```xml
|
|
46
47
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
@@ -62,6 +63,7 @@ sitemap({
|
|
|
62
63
|
routes: ['/about'],
|
|
63
64
|
})
|
|
64
65
|
```
|
|
66
|
+
|
|
65
67
|
*Output:*
|
|
66
68
|
```xml
|
|
67
69
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
@@ -73,13 +75,88 @@ sitemap({
|
|
|
73
75
|
</urlset>
|
|
74
76
|
```
|
|
75
77
|
|
|
78
|
+
### With route objects:
|
|
79
|
+
|
|
80
|
+
Route objects (aka. `SitemapEntry` objects) allow for full control over "loc", "lastmod", "changefreq", "priority" and "hreflang".
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
sitemap({
|
|
84
|
+
hostname: 'https://example.com',
|
|
85
|
+
routes: [
|
|
86
|
+
'/',
|
|
87
|
+
'/about',
|
|
88
|
+
{
|
|
89
|
+
loc: '/blog',
|
|
90
|
+
lastmod: '2026-01-01',
|
|
91
|
+
changefreq: 'weekly',
|
|
92
|
+
priority: 0.8
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
})
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
*Output:*
|
|
99
|
+
```xml
|
|
100
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
101
|
+
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
102
|
+
<url>
|
|
103
|
+
<loc>https://example.com/</loc>
|
|
104
|
+
<lastmod>2026-03-14T20:31:12.450Z</lastmod>
|
|
105
|
+
</url>
|
|
106
|
+
<url>
|
|
107
|
+
<loc>https://example.com/about</loc>
|
|
108
|
+
<lastmod>2026-03-14T20:31:12.450Z</lastmod>
|
|
109
|
+
</url>
|
|
110
|
+
<url>
|
|
111
|
+
<loc>https://example.com/blog</loc>
|
|
112
|
+
<lastmod>2026-01-01</lastmod>
|
|
113
|
+
<changefreq>weekly</changefreq>
|
|
114
|
+
<priority>0.8</priority>
|
|
115
|
+
</url>
|
|
116
|
+
</urlset>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### With hreflang (i18n support):
|
|
120
|
+
|
|
121
|
+
Use the `hreflang` property on a `SitemapEntry` to define alternate language versions of a page.
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
sitemap({
|
|
125
|
+
hostname: 'https://example.com',
|
|
126
|
+
routes: [
|
|
127
|
+
{
|
|
128
|
+
loc: '/about',
|
|
129
|
+
hreflang: [
|
|
130
|
+
{ lang: 'en', href: 'https://example.com/about' },
|
|
131
|
+
{ lang: 'de', href: 'https://example.com/de/ueber' },
|
|
132
|
+
{ lang: 'x-default', href: 'https://example.com/about' },
|
|
133
|
+
],
|
|
134
|
+
},
|
|
135
|
+
],
|
|
136
|
+
})
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
*Output:*
|
|
140
|
+
```xml
|
|
141
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
142
|
+
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">
|
|
143
|
+
<url>
|
|
144
|
+
<loc>https://example.com/about</loc>
|
|
145
|
+
<lastmod>2026-03-14T21:02:53.166Z</lastmod>
|
|
146
|
+
<xhtml:link rel="alternate" hreflang="en" href="https://example.com/about" />
|
|
147
|
+
<xhtml:link rel="alternate" hreflang="de" href="https://example.com/de/ueber" />
|
|
148
|
+
<xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/about" />
|
|
149
|
+
</url>
|
|
150
|
+
</urlset>
|
|
151
|
+
```
|
|
152
|
+
|
|
76
153
|
## Options
|
|
77
154
|
|
|
78
155
|
The `hostname` option is required. All other options are optional.
|
|
79
156
|
|
|
80
|
-
| Option | Type
|
|
81
|
-
|
|
82
|
-
| hostname | *string*
|
|
83
|
-
| enabled | *boolean*
|
|
84
|
-
| routes | *string[]* | `['/']` | An array of routes to include in the sitemap |
|
|
157
|
+
| Option | Type | Default | Description |
|
|
158
|
+
|----------|---------------------------------------------------|---------|----------------------------------------------------------------------|
|
|
159
|
+
| hostname | *string* | - | The hostname of the site, used to build the full URLs in the sitemap |
|
|
160
|
+
| enabled | *boolean* | `true` | Toggle the plugin on or off |
|
|
161
|
+
| routes | *(string \| [SitemapEntry](./src/types.ts#L8))[]* | `['/']` | An array of routes to include in the sitemap |
|
|
85
162
|
|
package/dist/index.cjs
CHANGED
|
@@ -42,8 +42,8 @@ var import_node_path = __toESM(require("path"), 1);
|
|
|
42
42
|
var SPACER = " ";
|
|
43
43
|
var DSPACER = SPACER + SPACER;
|
|
44
44
|
var xmlHeader = `<?xml version="1.0" encoding="UTF-8"?>`;
|
|
45
|
-
var xmlSchema = (content) => {
|
|
46
|
-
return `<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
45
|
+
var xmlSchema = (content, hasHreflang) => {
|
|
46
|
+
return `<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"${hasHreflang ? ' xmlns:xhtml="http://www.w3.org/1999/xhtml"' : ""}>
|
|
47
47
|
${content}
|
|
48
48
|
</urlset>`;
|
|
49
49
|
};
|
|
@@ -66,6 +66,7 @@ var escapeXml = (value) => {
|
|
|
66
66
|
});
|
|
67
67
|
};
|
|
68
68
|
var generateSitemap = (entries) => {
|
|
69
|
+
let hasHreflang = false;
|
|
69
70
|
const urls = entries.map((entry) => {
|
|
70
71
|
let sitemapEntry = `${DSPACER}<loc>${escapeXml(entry.loc)}</loc>`;
|
|
71
72
|
if (entry.lastmod) {
|
|
@@ -80,20 +81,34 @@ ${DSPACER}<changefreq>${escapeXml(entry.changefreq)}</changefreq>`;
|
|
|
80
81
|
sitemapEntry += `
|
|
81
82
|
${DSPACER}<priority>${escapeXml(entry.priority)}</priority>`;
|
|
82
83
|
}
|
|
84
|
+
if (entry.hreflang?.length) {
|
|
85
|
+
hasHreflang = true;
|
|
86
|
+
entry.hreflang.forEach((alt) => {
|
|
87
|
+
sitemapEntry += `
|
|
88
|
+
${DSPACER}<xhtml:link rel="alternate" hreflang="${escapeXml(alt.lang)}" href="${escapeXml(alt.href)}" />`;
|
|
89
|
+
});
|
|
90
|
+
}
|
|
83
91
|
return `${SPACER}<url>
|
|
84
92
|
${sitemapEntry}
|
|
85
93
|
${SPACER}</url>`;
|
|
86
94
|
}).join("\n");
|
|
87
95
|
return `${xmlHeader}
|
|
88
|
-
${xmlSchema(urls)}`;
|
|
96
|
+
${xmlSchema(urls, hasHreflang)}`;
|
|
89
97
|
};
|
|
90
98
|
var buildSitemapEntries = (options) => {
|
|
91
99
|
const host = options.hostname.replace(/\/$/, "");
|
|
92
100
|
const lastmod = (/* @__PURE__ */ new Date()).toISOString();
|
|
93
101
|
return options.routes.map((route) => {
|
|
102
|
+
if (typeof route === "string") {
|
|
103
|
+
return {
|
|
104
|
+
loc: `${host}/${route.replace(/^\/+/, "")}`,
|
|
105
|
+
lastmod
|
|
106
|
+
};
|
|
107
|
+
}
|
|
94
108
|
return {
|
|
95
|
-
|
|
96
|
-
|
|
109
|
+
...route,
|
|
110
|
+
loc: `${host}/${route.loc.replace(/^\/+/, "")}`,
|
|
111
|
+
lastmod: route.lastmod ?? lastmod
|
|
97
112
|
};
|
|
98
113
|
});
|
|
99
114
|
};
|
package/dist/index.d.cts
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import { Plugin } from 'vite';
|
|
2
2
|
|
|
3
3
|
type ChangeFreq = 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never';
|
|
4
|
+
type HrefLangEntry = {
|
|
5
|
+
lang: string;
|
|
6
|
+
href: string;
|
|
7
|
+
};
|
|
4
8
|
type SitemapEntry = {
|
|
5
9
|
loc: string;
|
|
6
10
|
lastmod?: string;
|
|
7
11
|
priority?: number;
|
|
8
12
|
changefreq?: ChangeFreq;
|
|
13
|
+
hreflang?: HrefLangEntry[];
|
|
9
14
|
};
|
|
10
15
|
type Options = {
|
|
11
16
|
/**
|
|
@@ -21,13 +26,25 @@ type Options = {
|
|
|
21
26
|
*/
|
|
22
27
|
hostname: string;
|
|
23
28
|
/**
|
|
24
|
-
*
|
|
29
|
+
* The routes to include in the sitemap. Pass either strings or `SitemapEntry` objects
|
|
30
|
+
* for full control over "loc", "lastmod", "changefreq", "priority" and "hreflang".
|
|
25
31
|
*
|
|
26
32
|
* **Default: `['/']`**
|
|
33
|
+
*
|
|
34
|
+
* ---
|
|
35
|
+
*
|
|
36
|
+
* Example:
|
|
37
|
+
* ```ts
|
|
38
|
+
* routes: [
|
|
39
|
+
* '/',
|
|
40
|
+
* '/about',
|
|
41
|
+
* { loc: '/blog', lastmod: '2026-01-01', changefreq: 'weekly', priority: 0.8 },
|
|
42
|
+
* ]
|
|
43
|
+
* ```
|
|
27
44
|
*/
|
|
28
|
-
routes?: string[];
|
|
45
|
+
routes?: (string | SitemapEntry)[];
|
|
29
46
|
};
|
|
30
47
|
|
|
31
48
|
declare function sitemap(options: Options): Plugin;
|
|
32
49
|
|
|
33
|
-
export { type ChangeFreq, type Options, type SitemapEntry, sitemap };
|
|
50
|
+
export { type ChangeFreq, type HrefLangEntry, type Options, type SitemapEntry, sitemap };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import { Plugin } from 'vite';
|
|
2
2
|
|
|
3
3
|
type ChangeFreq = 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never';
|
|
4
|
+
type HrefLangEntry = {
|
|
5
|
+
lang: string;
|
|
6
|
+
href: string;
|
|
7
|
+
};
|
|
4
8
|
type SitemapEntry = {
|
|
5
9
|
loc: string;
|
|
6
10
|
lastmod?: string;
|
|
7
11
|
priority?: number;
|
|
8
12
|
changefreq?: ChangeFreq;
|
|
13
|
+
hreflang?: HrefLangEntry[];
|
|
9
14
|
};
|
|
10
15
|
type Options = {
|
|
11
16
|
/**
|
|
@@ -21,13 +26,25 @@ type Options = {
|
|
|
21
26
|
*/
|
|
22
27
|
hostname: string;
|
|
23
28
|
/**
|
|
24
|
-
*
|
|
29
|
+
* The routes to include in the sitemap. Pass either strings or `SitemapEntry` objects
|
|
30
|
+
* for full control over "loc", "lastmod", "changefreq", "priority" and "hreflang".
|
|
25
31
|
*
|
|
26
32
|
* **Default: `['/']`**
|
|
33
|
+
*
|
|
34
|
+
* ---
|
|
35
|
+
*
|
|
36
|
+
* Example:
|
|
37
|
+
* ```ts
|
|
38
|
+
* routes: [
|
|
39
|
+
* '/',
|
|
40
|
+
* '/about',
|
|
41
|
+
* { loc: '/blog', lastmod: '2026-01-01', changefreq: 'weekly', priority: 0.8 },
|
|
42
|
+
* ]
|
|
43
|
+
* ```
|
|
27
44
|
*/
|
|
28
|
-
routes?: string[];
|
|
45
|
+
routes?: (string | SitemapEntry)[];
|
|
29
46
|
};
|
|
30
47
|
|
|
31
48
|
declare function sitemap(options: Options): Plugin;
|
|
32
49
|
|
|
33
|
-
export { type ChangeFreq, type Options, type SitemapEntry, sitemap };
|
|
50
|
+
export { type ChangeFreq, type HrefLangEntry, type Options, type SitemapEntry, sitemap };
|
package/dist/index.js
CHANGED
|
@@ -6,8 +6,8 @@ import path from "path";
|
|
|
6
6
|
var SPACER = " ";
|
|
7
7
|
var DSPACER = SPACER + SPACER;
|
|
8
8
|
var xmlHeader = `<?xml version="1.0" encoding="UTF-8"?>`;
|
|
9
|
-
var xmlSchema = (content) => {
|
|
10
|
-
return `<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
9
|
+
var xmlSchema = (content, hasHreflang) => {
|
|
10
|
+
return `<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"${hasHreflang ? ' xmlns:xhtml="http://www.w3.org/1999/xhtml"' : ""}>
|
|
11
11
|
${content}
|
|
12
12
|
</urlset>`;
|
|
13
13
|
};
|
|
@@ -30,6 +30,7 @@ var escapeXml = (value) => {
|
|
|
30
30
|
});
|
|
31
31
|
};
|
|
32
32
|
var generateSitemap = (entries) => {
|
|
33
|
+
let hasHreflang = false;
|
|
33
34
|
const urls = entries.map((entry) => {
|
|
34
35
|
let sitemapEntry = `${DSPACER}<loc>${escapeXml(entry.loc)}</loc>`;
|
|
35
36
|
if (entry.lastmod) {
|
|
@@ -44,20 +45,34 @@ ${DSPACER}<changefreq>${escapeXml(entry.changefreq)}</changefreq>`;
|
|
|
44
45
|
sitemapEntry += `
|
|
45
46
|
${DSPACER}<priority>${escapeXml(entry.priority)}</priority>`;
|
|
46
47
|
}
|
|
48
|
+
if (entry.hreflang?.length) {
|
|
49
|
+
hasHreflang = true;
|
|
50
|
+
entry.hreflang.forEach((alt) => {
|
|
51
|
+
sitemapEntry += `
|
|
52
|
+
${DSPACER}<xhtml:link rel="alternate" hreflang="${escapeXml(alt.lang)}" href="${escapeXml(alt.href)}" />`;
|
|
53
|
+
});
|
|
54
|
+
}
|
|
47
55
|
return `${SPACER}<url>
|
|
48
56
|
${sitemapEntry}
|
|
49
57
|
${SPACER}</url>`;
|
|
50
58
|
}).join("\n");
|
|
51
59
|
return `${xmlHeader}
|
|
52
|
-
${xmlSchema(urls)}`;
|
|
60
|
+
${xmlSchema(urls, hasHreflang)}`;
|
|
53
61
|
};
|
|
54
62
|
var buildSitemapEntries = (options) => {
|
|
55
63
|
const host = options.hostname.replace(/\/$/, "");
|
|
56
64
|
const lastmod = (/* @__PURE__ */ new Date()).toISOString();
|
|
57
65
|
return options.routes.map((route) => {
|
|
66
|
+
if (typeof route === "string") {
|
|
67
|
+
return {
|
|
68
|
+
loc: `${host}/${route.replace(/^\/+/, "")}`,
|
|
69
|
+
lastmod
|
|
70
|
+
};
|
|
71
|
+
}
|
|
58
72
|
return {
|
|
59
|
-
|
|
60
|
-
|
|
73
|
+
...route,
|
|
74
|
+
loc: `${host}/${route.loc.replace(/^\/+/, "")}`,
|
|
75
|
+
lastmod: route.lastmod ?? lastmod
|
|
61
76
|
};
|
|
62
77
|
});
|
|
63
78
|
};
|
package/package.json
CHANGED