vite-plugin-sitemap-ts 1.3.1 → 1.4.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 CHANGED
@@ -48,7 +48,7 @@ sitemap({
48
48
  <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
49
49
  <url>
50
50
  <loc>https://example.com/</loc>
51
- <lastmod>2026-03-14T19:27:44.429Z</lastmod>
51
+ <lastmod>2026-03-14</lastmod>
52
52
  </url>
53
53
  </urlset>
54
54
  ```
@@ -70,7 +70,7 @@ sitemap({
70
70
  <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
71
71
  <url>
72
72
  <loc>https://example.com/about</loc>
73
- <lastmod>2026-03-14T19:42:17.729Z</lastmod>
73
+ <lastmod>2026-03-14</lastmod>
74
74
  </url>
75
75
  </urlset>
76
76
  ```
@@ -101,11 +101,11 @@ sitemap({
101
101
  <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
102
102
  <url>
103
103
  <loc>https://example.com/</loc>
104
- <lastmod>2026-03-14T20:31:12.450Z</lastmod>
104
+ <lastmod>2026-03-14</lastmod>
105
105
  </url>
106
106
  <url>
107
107
  <loc>https://example.com/about</loc>
108
- <lastmod>2026-03-14T20:31:12.450Z</lastmod>
108
+ <lastmod>2026-03-14</lastmod>
109
109
  </url>
110
110
  <url>
111
111
  <loc>https://example.com/blog</loc>
@@ -142,7 +142,7 @@ sitemap({
142
142
  <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">
143
143
  <url>
144
144
  <loc>https://example.com/about</loc>
145
- <lastmod>2026-03-14T21:02:53.166Z</lastmod>
145
+ <lastmod>2026-03-14</lastmod>
146
146
  <xhtml:link rel="alternate" hreflang="en" href="https://example.com/about" />
147
147
  <xhtml:link rel="alternate" hreflang="de" href="https://example.com/de/ueber" />
148
148
  <xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/about" />
@@ -154,9 +154,9 @@ sitemap({
154
154
 
155
155
  The `hostname` option is required. All other options are optional.
156
156
 
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 |
162
-
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 |
162
+ | outDir | *string* | - | Custom output directory for `sitemap.xml` (resolved relative to project root) |
package/dist/index.cjs CHANGED
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __export = (target, all) => {
9
7
  for (var name in all)
@@ -17,14 +15,6 @@ var __copyProps = (to, from, except, desc) => {
17
15
  }
18
16
  return to;
19
17
  };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
19
 
30
20
  // src/index.ts
@@ -35,8 +25,8 @@ __export(index_exports, {
35
25
  module.exports = __toCommonJS(index_exports);
36
26
 
37
27
  // src/plugin.ts
38
- var import_node_fs = __toESM(require("fs"), 1);
39
- var import_node_path = __toESM(require("path"), 1);
28
+ var import_node_fs = require("fs");
29
+ var import_node_path = require("path");
40
30
 
41
31
  // src/utils.ts
42
32
  var SPACER = " ";
@@ -97,7 +87,7 @@ ${xmlSchema(urls, hasHreflang)}`;
97
87
  };
98
88
  var buildSitemapEntries = (options) => {
99
89
  const host = options.hostname.replace(/\/$/, "");
100
- const lastmod = (/* @__PURE__ */ new Date()).toISOString();
90
+ const lastmod = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
101
91
  return options.routes.map((route) => {
102
92
  if (typeof route === "string") {
103
93
  return {
@@ -128,6 +118,16 @@ var LOGGER_CLEAR = "\x1B[0m";
128
118
  var LOGGER_PREFIX = logColor("yellow", "[sitemap-ts]", true);
129
119
  var LOGGER_SUCCESS = logColor("green", "\u2713", true);
130
120
  var LOGGER_FAILURE = logColor("red", "\u2717", true);
121
+ var logStart = (config, path) => {
122
+ config.logger.info(`
123
+ ${LOGGER_CLEAR}- ${LOGGER_PREFIX} Writing sitemap.xml at ${path}`);
124
+ };
125
+ var logSuccess = (config) => {
126
+ config.logger.info(`${LOGGER_CLEAR}${LOGGER_SUCCESS} ${LOGGER_PREFIX} Success`);
127
+ };
128
+ var getErrorMsg = (err) => {
129
+ return `Failed to write sitemap.xml! ${err instanceof Error ? err.message : String(err)}`;
130
+ };
131
131
 
132
132
  // src/plugin.ts
133
133
  var BASE_PATH = "/";
@@ -138,6 +138,7 @@ function sitemap(options) {
138
138
  const enabled = options.enabled ?? true;
139
139
  const host = options.hostname ?? void 0;
140
140
  const routes = options.routes?.length ? options.routes : ["/"];
141
+ const customOutDir = options.outDir ?? void 0;
141
142
  if (!host) {
142
143
  throw new Error("Sitemap hostname is not set and required to build the sitemap.");
143
144
  }
@@ -157,6 +158,11 @@ function sitemap(options) {
157
158
  config.logger.info(
158
159
  `${LOGGER_CLEAR}${LOGGER_SUCCESS} ${LOGGER_PREFIX} Exposed new route: ${logColor("green", SITEMAP_PATH)}`
159
160
  );
161
+ if (customOutDir) {
162
+ config.logger.info(
163
+ `${LOGGER_CLEAR}- ${LOGGER_PREFIX} Custom outDir: ${logColor("green", customOutDir)} (will be used during build)`
164
+ );
165
+ }
160
166
  },
161
167
  closeBundle() {
162
168
  if (this.environment) {
@@ -164,18 +170,31 @@ function sitemap(options) {
164
170
  return;
165
171
  }
166
172
  }
167
- const outDir = config.build.outDir.endsWith("/server") ? config.build.outDir.replace(/\/server$/, "/client") : config.build.outDir;
168
- config.logger.info(`
169
- - ${LOGGER_CLEAR}${LOGGER_PREFIX} Writing sitemap.xml at ${outDir}${SITEMAP_PATH}`);
173
+ const entries = buildSitemapEntries({ hostname: host, routes });
174
+ const content = generateSitemap(entries);
175
+ if (customOutDir) {
176
+ try {
177
+ const normalisedOutDir = customOutDir.replace(/^\/+/, "");
178
+ const resolvedOutDir = (0, import_node_path.resolve)(config.root, normalisedOutDir);
179
+ const filePath = (0, import_node_path.join)(resolvedOutDir, FILE_NAME);
180
+ logStart(config, filePath);
181
+ (0, import_node_fs.mkdirSync)(resolvedOutDir, { recursive: true });
182
+ (0, import_node_fs.writeFileSync)(filePath, content, "utf-8");
183
+ logSuccess(config);
184
+ } catch (err) {
185
+ throw new Error(getErrorMsg(err));
186
+ }
187
+ return;
188
+ }
170
189
  try {
171
- const entries = buildSitemapEntries({ hostname: host, routes });
172
- const content = generateSitemap(entries);
173
- const outDirPath = import_node_path.default.resolve(config.root, outDir);
174
- const filePath = import_node_path.default.join(outDirPath, FILE_NAME);
175
- import_node_fs.default.writeFileSync(filePath, content, "utf-8");
176
- config.logger.info(`${LOGGER_CLEAR}${LOGGER_SUCCESS} ${LOGGER_PREFIX} Success`);
190
+ const normalisedOutDir = config.build.outDir.endsWith("/server") ? config.build.outDir.replace(/\/server$/, "/client") : config.build.outDir;
191
+ const resolvedOutDir = (0, import_node_path.resolve)(config.root, normalisedOutDir);
192
+ const filePath = (0, import_node_path.join)(resolvedOutDir, FILE_NAME);
193
+ logStart(config, filePath);
194
+ (0, import_node_fs.writeFileSync)(filePath, content, "utf-8");
195
+ logSuccess(config);
177
196
  } catch (err) {
178
- throw new Error(`Failed to write sitemap.xml! ${err instanceof Error ? err.message : String(err)}`);
197
+ throw new Error(getErrorMsg(err));
179
198
  }
180
199
  }
181
200
  };
package/dist/index.d.cts CHANGED
@@ -34,7 +34,7 @@ type Options = {
34
34
  * ---
35
35
  *
36
36
  * Example:
37
- * ```ts
37
+ * ```typescript
38
38
  * routes: [
39
39
  * '/',
40
40
  * '/about',
@@ -43,6 +43,24 @@ type Options = {
43
43
  * ```
44
44
  */
45
45
  routes?: (string | SitemapEntry)[];
46
+ /**
47
+ * Custom output directory for the generated `sitemap.xml` file. When specified, the file is
48
+ * written to this directory instead of the default Vite build output directory.
49
+ *
50
+ * The path is resolved relative to the Vite project root.
51
+ *
52
+ * **Default: `undefined`** (uses Vite's `build.outDir`)
53
+ *
54
+ * ---
55
+ *
56
+ * Example:
57
+ * ```typescript
58
+ * sitemap({
59
+ * outDir: 'public',
60
+ * })
61
+ * ```
62
+ */
63
+ outDir?: string;
46
64
  };
47
65
 
48
66
  declare function sitemap(options: Options): Plugin;
package/dist/index.d.ts CHANGED
@@ -34,7 +34,7 @@ type Options = {
34
34
  * ---
35
35
  *
36
36
  * Example:
37
- * ```ts
37
+ * ```typescript
38
38
  * routes: [
39
39
  * '/',
40
40
  * '/about',
@@ -43,6 +43,24 @@ type Options = {
43
43
  * ```
44
44
  */
45
45
  routes?: (string | SitemapEntry)[];
46
+ /**
47
+ * Custom output directory for the generated `sitemap.xml` file. When specified, the file is
48
+ * written to this directory instead of the default Vite build output directory.
49
+ *
50
+ * The path is resolved relative to the Vite project root.
51
+ *
52
+ * **Default: `undefined`** (uses Vite's `build.outDir`)
53
+ *
54
+ * ---
55
+ *
56
+ * Example:
57
+ * ```typescript
58
+ * sitemap({
59
+ * outDir: 'public',
60
+ * })
61
+ * ```
62
+ */
63
+ outDir?: string;
46
64
  };
47
65
 
48
66
  declare function sitemap(options: Options): Plugin;
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/plugin.ts
2
- import fs from "fs";
3
- import path from "path";
2
+ import { mkdirSync, writeFileSync } from "fs";
3
+ import { join, resolve } from "path";
4
4
 
5
5
  // src/utils.ts
6
6
  var SPACER = " ";
@@ -61,7 +61,7 @@ ${xmlSchema(urls, hasHreflang)}`;
61
61
  };
62
62
  var buildSitemapEntries = (options) => {
63
63
  const host = options.hostname.replace(/\/$/, "");
64
- const lastmod = (/* @__PURE__ */ new Date()).toISOString();
64
+ const lastmod = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
65
65
  return options.routes.map((route) => {
66
66
  if (typeof route === "string") {
67
67
  return {
@@ -92,6 +92,16 @@ var LOGGER_CLEAR = "\x1B[0m";
92
92
  var LOGGER_PREFIX = logColor("yellow", "[sitemap-ts]", true);
93
93
  var LOGGER_SUCCESS = logColor("green", "\u2713", true);
94
94
  var LOGGER_FAILURE = logColor("red", "\u2717", true);
95
+ var logStart = (config, path) => {
96
+ config.logger.info(`
97
+ ${LOGGER_CLEAR}- ${LOGGER_PREFIX} Writing sitemap.xml at ${path}`);
98
+ };
99
+ var logSuccess = (config) => {
100
+ config.logger.info(`${LOGGER_CLEAR}${LOGGER_SUCCESS} ${LOGGER_PREFIX} Success`);
101
+ };
102
+ var getErrorMsg = (err) => {
103
+ return `Failed to write sitemap.xml! ${err instanceof Error ? err.message : String(err)}`;
104
+ };
95
105
 
96
106
  // src/plugin.ts
97
107
  var BASE_PATH = "/";
@@ -102,6 +112,7 @@ function sitemap(options) {
102
112
  const enabled = options.enabled ?? true;
103
113
  const host = options.hostname ?? void 0;
104
114
  const routes = options.routes?.length ? options.routes : ["/"];
115
+ const customOutDir = options.outDir ?? void 0;
105
116
  if (!host) {
106
117
  throw new Error("Sitemap hostname is not set and required to build the sitemap.");
107
118
  }
@@ -121,6 +132,11 @@ function sitemap(options) {
121
132
  config.logger.info(
122
133
  `${LOGGER_CLEAR}${LOGGER_SUCCESS} ${LOGGER_PREFIX} Exposed new route: ${logColor("green", SITEMAP_PATH)}`
123
134
  );
135
+ if (customOutDir) {
136
+ config.logger.info(
137
+ `${LOGGER_CLEAR}- ${LOGGER_PREFIX} Custom outDir: ${logColor("green", customOutDir)} (will be used during build)`
138
+ );
139
+ }
124
140
  },
125
141
  closeBundle() {
126
142
  if (this.environment) {
@@ -128,18 +144,31 @@ function sitemap(options) {
128
144
  return;
129
145
  }
130
146
  }
131
- const outDir = config.build.outDir.endsWith("/server") ? config.build.outDir.replace(/\/server$/, "/client") : config.build.outDir;
132
- config.logger.info(`
133
- - ${LOGGER_CLEAR}${LOGGER_PREFIX} Writing sitemap.xml at ${outDir}${SITEMAP_PATH}`);
147
+ const entries = buildSitemapEntries({ hostname: host, routes });
148
+ const content = generateSitemap(entries);
149
+ if (customOutDir) {
150
+ try {
151
+ const normalisedOutDir = customOutDir.replace(/^\/+/, "");
152
+ const resolvedOutDir = resolve(config.root, normalisedOutDir);
153
+ const filePath = join(resolvedOutDir, FILE_NAME);
154
+ logStart(config, filePath);
155
+ mkdirSync(resolvedOutDir, { recursive: true });
156
+ writeFileSync(filePath, content, "utf-8");
157
+ logSuccess(config);
158
+ } catch (err) {
159
+ throw new Error(getErrorMsg(err));
160
+ }
161
+ return;
162
+ }
134
163
  try {
135
- const entries = buildSitemapEntries({ hostname: host, routes });
136
- const content = generateSitemap(entries);
137
- const outDirPath = path.resolve(config.root, outDir);
138
- const filePath = path.join(outDirPath, FILE_NAME);
139
- fs.writeFileSync(filePath, content, "utf-8");
140
- config.logger.info(`${LOGGER_CLEAR}${LOGGER_SUCCESS} ${LOGGER_PREFIX} Success`);
164
+ const normalisedOutDir = config.build.outDir.endsWith("/server") ? config.build.outDir.replace(/\/server$/, "/client") : config.build.outDir;
165
+ const resolvedOutDir = resolve(config.root, normalisedOutDir);
166
+ const filePath = join(resolvedOutDir, FILE_NAME);
167
+ logStart(config, filePath);
168
+ writeFileSync(filePath, content, "utf-8");
169
+ logSuccess(config);
141
170
  } catch (err) {
142
- throw new Error(`Failed to write sitemap.xml! ${err instanceof Error ? err.message : String(err)}`);
171
+ throw new Error(getErrorMsg(err));
143
172
  }
144
173
  }
145
174
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-plugin-sitemap-ts",
3
- "version": "1.3.1",
3
+ "version": "1.4.0",
4
4
  "description": "Vite plugin to generate sitemap.xml. Works in dev mode.",
5
5
  "author": "Cornelius Weidmann <cornelius@kyco.io> (https://kyco.io)",
6
6
  "license": "MIT",