@tanstack/start-plugin-core 1.121.0-alpha.4 → 1.121.0-alpha.6

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.
@@ -74,9 +74,11 @@ function createTanStackStartOptionsSchema(frameworkPlugin = {}) {
74
74
  dir: z.string().optional().default("public"),
75
75
  base: z.string().optional().default("/")
76
76
  }).optional().default({}),
77
- pages: z.array(z.union([z.string(), pageSchema])).optional().default([]),
78
- sitemap: pagePrerenderOptionsSchema.extend({
79
- host: z.string().optional()
77
+ pages: z.array(pageSchema).optional().default([]),
78
+ sitemap: z.object({
79
+ enabled: z.boolean().optional().default(true),
80
+ host: z.string().optional(),
81
+ outputPath: z.string().optional().default("sitemap.xml")
80
82
  }).optional(),
81
83
  prerender: z.object({
82
84
  enabled: z.boolean().optional(),
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sources":["../../src/schema.ts"],"sourcesContent":["import path from 'node:path'\nimport { existsSync } from 'node:fs'\nimport { z } from 'zod'\nimport { configSchema, getConfig } from '@tanstack/router-generator'\nimport type { NitroConfig } from 'nitropack'\n\nconst tsrConfig = configSchema\n .omit({ autoCodeSplitting: true })\n .partial()\n .extend({\n srcDirectory: z.string().optional().default('src'),\n })\n\nexport function createTanStackConfig<\n TFrameworkPlugin extends Record<string, unknown>,\n>(frameworkPlugin?: TFrameworkPlugin) {\n const schema = createTanStackStartOptionsSchema(frameworkPlugin)\n\n return {\n schema,\n parse: (opts?: z.input<typeof schema>) => {\n const options = schema.parse(opts)\n\n const srcDirectory = options.tsr.srcDirectory\n\n const routesDirectory =\n options.tsr.routesDirectory ?? path.join(srcDirectory, 'routes')\n\n const generatedRouteTree =\n options.tsr.generatedRouteTree ??\n path.join(srcDirectory, 'routeTree.gen.ts')\n\n const clientEntryPath = (() => {\n if (options.client.entry) {\n return path.join(srcDirectory, options.client.entry)\n }\n\n if (existsSync(path.join(srcDirectory, 'client.tsx'))) {\n return path.join(srcDirectory, 'client.tsx')\n }\n\n return '/~start/default-client-entry'\n })()\n\n const serverEntryPath = (() => {\n if (options.server.entry) {\n return path.join(srcDirectory, options.server.entry)\n }\n\n if (existsSync(path.join(srcDirectory, 'server.tsx'))) {\n return path.join(srcDirectory, 'server.tsx')\n }\n\n if (existsSync(path.join(srcDirectory, 'server.ts'))) {\n return path.join(srcDirectory, 'server.ts')\n }\n\n if (existsSync(path.join(srcDirectory, 'server.js'))) {\n return path.join(srcDirectory, 'server.js')\n }\n\n return '/~start/default-server-entry'\n })()\n\n return {\n ...options,\n tsr: {\n ...options.tsr,\n ...getConfig({\n ...options.tsr,\n routesDirectory,\n generatedRouteTree,\n }),\n },\n clientEntryPath,\n serverEntryPath,\n }\n },\n }\n}\n\nexport function createTanStackStartOptionsSchema(\n frameworkPlugin: Record<string, unknown> = {},\n) {\n return z\n .object({\n root: z.string().optional().default(process.cwd()),\n target: z.custom<NitroConfig['preset']>().optional(),\n ...frameworkPlugin,\n tsr: tsrConfig.optional().default({}),\n client: z\n .object({\n entry: z.string().optional(),\n base: z.string().optional().default('/_build'),\n })\n .optional()\n .default({}),\n server: z\n .object({\n entry: z.string().optional(),\n })\n .optional()\n .default({}),\n serverFns: z\n .object({\n base: z.string().optional().default('/_serverFn'),\n })\n .optional()\n .default({}),\n public: z\n .object({\n dir: z.string().optional().default('public'),\n base: z.string().optional().default('/'),\n })\n .optional()\n .default({}),\n pages: z\n .array(z.union([z.string(), pageSchema]))\n .optional()\n .default([]),\n sitemap: pagePrerenderOptionsSchema\n .extend({\n host: z.string().optional(),\n })\n .optional(),\n prerender: z\n .object({\n enabled: z.boolean().optional(),\n concurrency: z.number().optional(),\n filter: z.function().args(pageSchema).returns(z.any()).optional(),\n failOnError: z.boolean().optional(),\n })\n .and(pagePrerenderOptionsSchema.optional())\n .optional(),\n spa: spaSchema.optional(),\n })\n .optional()\n .default({})\n}\n\nconst pageSitemapOptionsSchema = z.object({\n exclude: z.boolean().optional(),\n priority: z.number().min(0).max(1).optional(),\n changefreq: z\n .enum(['always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', 'never'])\n .optional(),\n lastmod: z.union([z.string(), z.date()]).optional(),\n alternateRefs: z\n .array(\n z.object({\n href: z.string(),\n hreflang: z.string(),\n }),\n )\n .optional(),\n images: z\n .array(\n z.object({\n loc: z.string(),\n caption: z.string().optional(),\n title: z.string().optional(),\n }),\n )\n .optional(),\n news: z\n .object({\n publication: z.object({\n name: z.string(),\n language: z.string(),\n }),\n publicationDate: z.union([z.string(), z.date()]),\n title: z.string(),\n })\n .optional(),\n})\n\nconst pageBaseSchema = z.object({\n path: z.string(),\n sitemap: pageSitemapOptionsSchema.optional(),\n fromCrawl: z.boolean().optional(),\n})\n\nconst pagePrerenderOptionsSchema = z.object({\n enabled: z.boolean().optional(),\n outputPath: z.string().optional(),\n autoSubfolderIndex: z.boolean().optional(),\n crawlLinks: z.boolean().optional(),\n retryCount: z.number().optional(),\n retryDelay: z.number().optional(),\n onSuccess: z\n .function()\n .args(\n z.object({\n page: pageBaseSchema,\n html: z.string(),\n }),\n )\n .returns(z.any())\n .optional(),\n})\n\nconst spaSchema = z.object({\n enabled: z.boolean().optional().default(true),\n maskPath: z.string().optional().default('/'),\n prerender: pagePrerenderOptionsSchema\n .optional()\n .default({})\n .transform((opts) => ({\n outputPath: opts.outputPath ?? '/_shell',\n crawlLinks: false,\n retryCount: 0,\n ...opts,\n enabled: true,\n })),\n})\n\nexport const pageSchema = pageBaseSchema.extend({\n prerender: pagePrerenderOptionsSchema.optional(),\n})\n\nexport type Page = z.infer<typeof pageSchema>\n"],"names":[],"mappings":";;;;AAMA,MAAM,YAAY,aACf,KAAK,EAAE,mBAAmB,MAAM,EAChC,QAAQ,EACR,OAAO;AAAA,EACN,cAAc,EAAE,OAAA,EAAS,SAAS,EAAE,QAAQ,KAAK;AACnD,CAAC;AAEI,SAAS,qBAEd,iBAAoC;AAC9B,QAAA,SAAS,iCAAiC,eAAe;AAExD,SAAA;AAAA,IACL;AAAA,IACA,OAAO,CAAC,SAAkC;AAClC,YAAA,UAAU,OAAO,MAAM,IAAI;AAE3B,YAAA,eAAe,QAAQ,IAAI;AAEjC,YAAM,kBACJ,QAAQ,IAAI,mBAAmB,KAAK,KAAK,cAAc,QAAQ;AAEjE,YAAM,qBACJ,QAAQ,IAAI,sBACZ,KAAK,KAAK,cAAc,kBAAkB;AAE5C,YAAM,mBAAmB,MAAM;AACzB,YAAA,QAAQ,OAAO,OAAO;AACxB,iBAAO,KAAK,KAAK,cAAc,QAAQ,OAAO,KAAK;AAAA,QAAA;AAGrD,YAAI,WAAW,KAAK,KAAK,cAAc,YAAY,CAAC,GAAG;AAC9C,iBAAA,KAAK,KAAK,cAAc,YAAY;AAAA,QAAA;AAGtC,eAAA;AAAA,MAAA,GACN;AAEH,YAAM,mBAAmB,MAAM;AACzB,YAAA,QAAQ,OAAO,OAAO;AACxB,iBAAO,KAAK,KAAK,cAAc,QAAQ,OAAO,KAAK;AAAA,QAAA;AAGrD,YAAI,WAAW,KAAK,KAAK,cAAc,YAAY,CAAC,GAAG;AAC9C,iBAAA,KAAK,KAAK,cAAc,YAAY;AAAA,QAAA;AAG7C,YAAI,WAAW,KAAK,KAAK,cAAc,WAAW,CAAC,GAAG;AAC7C,iBAAA,KAAK,KAAK,cAAc,WAAW;AAAA,QAAA;AAG5C,YAAI,WAAW,KAAK,KAAK,cAAc,WAAW,CAAC,GAAG;AAC7C,iBAAA,KAAK,KAAK,cAAc,WAAW;AAAA,QAAA;AAGrC,eAAA;AAAA,MAAA,GACN;AAEI,aAAA;AAAA,QACL,GAAG;AAAA,QACH,KAAK;AAAA,UACH,GAAG,QAAQ;AAAA,UACX,GAAG,UAAU;AAAA,YACX,GAAG,QAAQ;AAAA,YACX;AAAA,YACA;AAAA,UACD,CAAA;AAAA,QACH;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IAAA;AAAA,EAEJ;AACF;AAEgB,SAAA,iCACd,kBAA2C,IAC3C;AACA,SAAO,EACJ,OAAO;AAAA,IACN,MAAM,EAAE,SAAS,SAAW,EAAA,QAAQ,QAAQ,KAAK;AAAA,IACjD,QAAQ,EAAE,OAA8B,EAAE,SAAS;AAAA,IACnD,GAAG;AAAA,IACH,KAAK,UAAU,WAAW,QAAQ,CAAA,CAAE;AAAA,IACpC,QAAQ,EACL,OAAO;AAAA,MACN,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,MAC3B,MAAM,EAAE,OAAA,EAAS,SAAS,EAAE,QAAQ,SAAS;AAAA,IAC9C,CAAA,EACA,SAAA,EACA,QAAQ,EAAE;AAAA,IACb,QAAQ,EACL,OAAO;AAAA,MACN,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,IAC5B,CAAA,EACA,SAAA,EACA,QAAQ,EAAE;AAAA,IACb,WAAW,EACR,OAAO;AAAA,MACN,MAAM,EAAE,OAAA,EAAS,SAAS,EAAE,QAAQ,YAAY;AAAA,IACjD,CAAA,EACA,SAAA,EACA,QAAQ,EAAE;AAAA,IACb,QAAQ,EACL,OAAO;AAAA,MACN,KAAK,EAAE,OAAA,EAAS,SAAS,EAAE,QAAQ,QAAQ;AAAA,MAC3C,MAAM,EAAE,OAAA,EAAS,SAAS,EAAE,QAAQ,GAAG;AAAA,IACxC,CAAA,EACA,SAAA,EACA,QAAQ,EAAE;AAAA,IACb,OAAO,EACJ,MAAM,EAAE,MAAM,CAAC,EAAE,OAAA,GAAU,UAAU,CAAC,CAAC,EACvC,WACA,QAAQ,CAAA,CAAE;AAAA,IACb,SAAS,2BACN,OAAO;AAAA,MACN,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,IAC3B,CAAA,EACA,SAAS;AAAA,IACZ,WAAW,EACR,OAAO;AAAA,MACN,SAAS,EAAE,QAAQ,EAAE,SAAS;AAAA,MAC9B,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA,MACjC,QAAQ,EAAE,SAAS,EAAE,KAAK,UAAU,EAAE,QAAQ,EAAE,IAAK,CAAA,EAAE,SAAS;AAAA,MAChE,aAAa,EAAE,QAAQ,EAAE,SAAS;AAAA,IACnC,CAAA,EACA,IAAI,2BAA2B,SAAU,CAAA,EACzC,SAAS;AAAA,IACZ,KAAK,UAAU,SAAS;AAAA,EACzB,CAAA,EACA,SAAA,EACA,QAAQ,EAAE;AACf;AAEA,MAAM,2BAA2B,EAAE,OAAO;AAAA,EACxC,SAAS,EAAE,QAAQ,EAAE,SAAS;AAAA,EAC9B,UAAU,EAAE,OAAA,EAAS,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EAC5C,YAAY,EACT,KAAK,CAAC,UAAU,UAAU,SAAS,UAAU,WAAW,UAAU,OAAO,CAAC,EAC1E,SAAS;AAAA,EACZ,SAAS,EAAE,MAAM,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC,EAAE,SAAS;AAAA,EAClD,eAAe,EACZ;AAAA,IACC,EAAE,OAAO;AAAA,MACP,MAAM,EAAE,OAAO;AAAA,MACf,UAAU,EAAE,OAAO;AAAA,IACpB,CAAA;AAAA,IAEF,SAAS;AAAA,EACZ,QAAQ,EACL;AAAA,IACC,EAAE,OAAO;AAAA,MACP,KAAK,EAAE,OAAO;AAAA,MACd,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA,MAC7B,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,IAC5B,CAAA;AAAA,IAEF,SAAS;AAAA,EACZ,MAAM,EACH,OAAO;AAAA,IACN,aAAa,EAAE,OAAO;AAAA,MACpB,MAAM,EAAE,OAAO;AAAA,MACf,UAAU,EAAE,OAAO;AAAA,IAAA,CACpB;AAAA,IACD,iBAAiB,EAAE,MAAM,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;AAAA,IAC/C,OAAO,EAAE,OAAO;AAAA,EACjB,CAAA,EACA,SAAS;AACd,CAAC;AAED,MAAM,iBAAiB,EAAE,OAAO;AAAA,EAC9B,MAAM,EAAE,OAAO;AAAA,EACf,SAAS,yBAAyB,SAAS;AAAA,EAC3C,WAAW,EAAE,QAAQ,EAAE,SAAS;AAClC,CAAC;AAED,MAAM,6BAA6B,EAAE,OAAO;AAAA,EAC1C,SAAS,EAAE,QAAQ,EAAE,SAAS;AAAA,EAC9B,YAAY,EAAE,OAAO,EAAE,SAAS;AAAA,EAChC,oBAAoB,EAAE,QAAQ,EAAE,SAAS;AAAA,EACzC,YAAY,EAAE,QAAQ,EAAE,SAAS;AAAA,EACjC,YAAY,EAAE,OAAO,EAAE,SAAS;AAAA,EAChC,YAAY,EAAE,OAAO,EAAE,SAAS;AAAA,EAChC,WAAW,EACR,SAAA,EACA;AAAA,IACC,EAAE,OAAO;AAAA,MACP,MAAM;AAAA,MACN,MAAM,EAAE,OAAO;AAAA,IAChB,CAAA;AAAA,IAEF,QAAQ,EAAE,IAAI,CAAC,EACf,SAAS;AACd,CAAC;AAED,MAAM,YAAY,EAAE,OAAO;AAAA,EACzB,SAAS,EAAE,QAAA,EAAU,SAAS,EAAE,QAAQ,IAAI;AAAA,EAC5C,UAAU,EAAE,OAAA,EAAS,SAAS,EAAE,QAAQ,GAAG;AAAA,EAC3C,WAAW,2BACR,WACA,QAAQ,CAAA,CAAE,EACV,UAAU,CAAC,UAAU;AAAA,IACpB,YAAY,KAAK,cAAc;AAAA,IAC/B,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,GAAG;AAAA,IACH,SAAS;AAAA,EAAA,EACT;AACN,CAAC;AAEY,MAAA,aAAa,eAAe,OAAO;AAAA,EAC9C,WAAW,2BAA2B,SAAS;AACjD,CAAC;"}
1
+ {"version":3,"file":"schema.js","sources":["../../src/schema.ts"],"sourcesContent":["import path from 'node:path'\nimport { existsSync } from 'node:fs'\nimport { z } from 'zod'\nimport { configSchema, getConfig } from '@tanstack/router-generator'\nimport type { NitroConfig } from 'nitropack'\n\nconst tsrConfig = configSchema\n .omit({ autoCodeSplitting: true })\n .partial()\n .extend({\n srcDirectory: z.string().optional().default('src'),\n })\n\nexport function createTanStackConfig<\n TFrameworkPlugin extends Record<string, unknown>,\n>(frameworkPlugin?: TFrameworkPlugin) {\n const schema = createTanStackStartOptionsSchema(frameworkPlugin)\n\n return {\n schema,\n parse: (opts?: z.input<typeof schema>) => {\n const options = schema.parse(opts)\n\n const srcDirectory = options.tsr.srcDirectory\n\n const routesDirectory =\n options.tsr.routesDirectory ?? path.join(srcDirectory, 'routes')\n\n const generatedRouteTree =\n options.tsr.generatedRouteTree ??\n path.join(srcDirectory, 'routeTree.gen.ts')\n\n const clientEntryPath = (() => {\n if (options.client.entry) {\n return path.join(srcDirectory, options.client.entry)\n }\n\n if (existsSync(path.join(srcDirectory, 'client.tsx'))) {\n return path.join(srcDirectory, 'client.tsx')\n }\n\n return '/~start/default-client-entry'\n })()\n\n const serverEntryPath = (() => {\n if (options.server.entry) {\n return path.join(srcDirectory, options.server.entry)\n }\n\n if (existsSync(path.join(srcDirectory, 'server.tsx'))) {\n return path.join(srcDirectory, 'server.tsx')\n }\n\n if (existsSync(path.join(srcDirectory, 'server.ts'))) {\n return path.join(srcDirectory, 'server.ts')\n }\n\n if (existsSync(path.join(srcDirectory, 'server.js'))) {\n return path.join(srcDirectory, 'server.js')\n }\n\n return '/~start/default-server-entry'\n })()\n\n return {\n ...options,\n tsr: {\n ...options.tsr,\n ...getConfig({\n ...options.tsr,\n routesDirectory,\n generatedRouteTree,\n }),\n },\n clientEntryPath,\n serverEntryPath,\n }\n },\n }\n}\n\nexport function createTanStackStartOptionsSchema(\n frameworkPlugin: Record<string, unknown> = {},\n) {\n return z\n .object({\n root: z.string().optional().default(process.cwd()),\n target: z.custom<NitroConfig['preset']>().optional(),\n ...frameworkPlugin,\n tsr: tsrConfig.optional().default({}),\n client: z\n .object({\n entry: z.string().optional(),\n base: z.string().optional().default('/_build'),\n })\n .optional()\n .default({}),\n server: z\n .object({\n entry: z.string().optional(),\n })\n .optional()\n .default({}),\n serverFns: z\n .object({\n base: z.string().optional().default('/_serverFn'),\n })\n .optional()\n .default({}),\n public: z\n .object({\n dir: z.string().optional().default('public'),\n base: z.string().optional().default('/'),\n })\n .optional()\n .default({}),\n pages: z.array(pageSchema).optional().default([]),\n sitemap: z\n .object({\n enabled: z.boolean().optional().default(true),\n host: z.string().optional(),\n outputPath: z.string().optional().default('sitemap.xml'),\n })\n .optional(),\n prerender: z\n .object({\n enabled: z.boolean().optional(),\n concurrency: z.number().optional(),\n filter: z.function().args(pageSchema).returns(z.any()).optional(),\n failOnError: z.boolean().optional(),\n })\n .and(pagePrerenderOptionsSchema.optional())\n .optional(),\n spa: spaSchema.optional(),\n })\n .optional()\n .default({})\n}\n\nconst pageSitemapOptionsSchema = z.object({\n exclude: z.boolean().optional(),\n priority: z.number().min(0).max(1).optional(),\n changefreq: z\n .enum(['always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', 'never'])\n .optional(),\n lastmod: z.union([z.string(), z.date()]).optional(),\n alternateRefs: z\n .array(\n z.object({\n href: z.string(),\n hreflang: z.string(),\n }),\n )\n .optional(),\n images: z\n .array(\n z.object({\n loc: z.string(),\n caption: z.string().optional(),\n title: z.string().optional(),\n }),\n )\n .optional(),\n news: z\n .object({\n publication: z.object({\n name: z.string(),\n language: z.string(),\n }),\n publicationDate: z.union([z.string(), z.date()]),\n title: z.string(),\n })\n .optional(),\n})\n\nconst pageBaseSchema = z.object({\n path: z.string(),\n sitemap: pageSitemapOptionsSchema.optional(),\n fromCrawl: z.boolean().optional(),\n})\n\nconst pagePrerenderOptionsSchema = z.object({\n enabled: z.boolean().optional(),\n outputPath: z.string().optional(),\n autoSubfolderIndex: z.boolean().optional(),\n crawlLinks: z.boolean().optional(),\n retryCount: z.number().optional(),\n retryDelay: z.number().optional(),\n onSuccess: z\n .function()\n .args(\n z.object({\n page: pageBaseSchema,\n html: z.string(),\n }),\n )\n .returns(z.any())\n .optional(),\n})\n\nconst spaSchema = z.object({\n enabled: z.boolean().optional().default(true),\n maskPath: z.string().optional().default('/'),\n prerender: pagePrerenderOptionsSchema\n .optional()\n .default({})\n .transform((opts) => ({\n outputPath: opts.outputPath ?? '/_shell',\n crawlLinks: false,\n retryCount: 0,\n ...opts,\n enabled: true,\n })),\n})\n\nexport const pageSchema = pageBaseSchema.extend({\n prerender: pagePrerenderOptionsSchema.optional(),\n})\n\nexport type Page = z.infer<typeof pageSchema>\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/start-plugin-core",
3
- "version": "1.121.0-alpha.4",
3
+ "version": "1.121.0-alpha.6",
4
4
  "description": "Modern and scalable routing for React applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -63,11 +63,11 @@
63
63
  "ufo": "^1.5.4",
64
64
  "xmlbuilder2": "^3.1.1",
65
65
  "zod": "^3.24.2",
66
- "@tanstack/router-generator": "^1.121.0-alpha.3",
66
+ "@tanstack/router-generator": "^1.121.0-alpha.5",
67
+ "@tanstack/router-plugin": "^1.121.0-alpha.5",
67
68
  "@tanstack/router-utils": "^1.121.0-alpha.2",
68
- "@tanstack/router-plugin": "^1.121.0-alpha.4",
69
69
  "@tanstack/server-functions-plugin": "^1.121.0-alpha.2",
70
- "@tanstack/router-core": "^1.121.0-alpha.3"
70
+ "@tanstack/router-core": "^1.121.0-alpha.5"
71
71
  },
72
72
  "devDependencies": {
73
73
  "vite": "^6.0.0"
@@ -0,0 +1,210 @@
1
+ import { writeFileSync } from 'node:fs'
2
+ import path from 'node:path'
3
+ import { create } from 'xmlbuilder2'
4
+ import type { TanStackStartOutputConfig } from './plugin'
5
+ import type { XMLBuilder } from 'xmlbuilder2/lib/interfaces'
6
+
7
+ export type SitemapUrl = {
8
+ loc: string
9
+ lastmod: string
10
+ priority?: number
11
+ changefreq?:
12
+ | 'always'
13
+ | 'hourly'
14
+ | 'daily'
15
+ | 'weekly'
16
+ | 'monthly'
17
+ | 'yearly'
18
+ | 'never'
19
+ alternateRefs?: Array<{
20
+ href: string
21
+ hreflang?: string
22
+ }>
23
+ images?: Array<{
24
+ loc: string
25
+ title?: string
26
+ caption?: string
27
+ }>
28
+ news?: {
29
+ publication: {
30
+ name: string
31
+ language: string
32
+ }
33
+ publicationDate: string | Date
34
+ title: string
35
+ }
36
+ }
37
+
38
+ export type SitemapData = {
39
+ urls: Array<SitemapUrl>
40
+ }
41
+
42
+ function buildSitemapJson(
43
+ pages: TanStackStartOutputConfig['pages'],
44
+ host: string,
45
+ ): SitemapData {
46
+ const slash = checkSlash(host)
47
+
48
+ const urls: Array<SitemapUrl> = pages
49
+ .filter((page) => {
50
+ return page.sitemap?.exclude !== true
51
+ })
52
+ .map((page) => ({
53
+ loc: `${host}${slash}${page.path.replace(/^\/+/g, '')}`,
54
+ lastmod: page.sitemap?.lastmod
55
+ ? new Date(page.sitemap.lastmod).toISOString().split('T')[0]!
56
+ : new Date().toISOString().split('T')[0]!,
57
+ priority: page.sitemap?.priority,
58
+ changefreq: page.sitemap?.changefreq,
59
+ alternateRefs: page.sitemap?.alternateRefs,
60
+ images: page.sitemap?.images,
61
+ news: page.sitemap?.news,
62
+ }))
63
+
64
+ return { urls }
65
+ }
66
+
67
+ function jsonToXml(sitemapData: SitemapData): string {
68
+ const sitemap = createXml('urlset')
69
+
70
+ for (const item of sitemapData.urls) {
71
+ const page = sitemap.ele('url')
72
+ page.ele('loc').txt(item.loc)
73
+ page.ele('lastmod').txt(item.lastmod)
74
+
75
+ if (item.priority !== undefined) {
76
+ page.ele('priority').txt(item.priority.toString())
77
+ }
78
+ if (item.changefreq) {
79
+ page.ele('changefreq').txt(item.changefreq)
80
+ }
81
+
82
+ // Add alternate references
83
+ if (item.alternateRefs?.length) {
84
+ for (const ref of item.alternateRefs) {
85
+ const alternateRef = page.ele('xhtml:link')
86
+ alternateRef.att('rel', 'alternate')
87
+ alternateRef.att('href', ref.href)
88
+ if (ref.hreflang) {
89
+ alternateRef.att('hreflang', ref.hreflang)
90
+ }
91
+ }
92
+ }
93
+
94
+ // Add images
95
+ if (item.images?.length) {
96
+ for (const image of item.images) {
97
+ const imageElement = page.ele('image:image')
98
+ imageElement.ele('image:loc').txt(image.loc)
99
+ if (image.title) {
100
+ imageElement.ele('image:title').txt(image.title)
101
+ }
102
+ if (image.caption) {
103
+ imageElement.ele('image:caption').txt(image.caption)
104
+ }
105
+ }
106
+ }
107
+
108
+ // Add news
109
+ if (item.news) {
110
+ const newsElement = page.ele('news:news')
111
+ const publication = newsElement.ele('news:publication')
112
+ publication.ele('news:name').txt(item.news.publication.name)
113
+ publication.ele('news:language').txt(item.news.publication.language)
114
+ newsElement
115
+ .ele('news:publication_date')
116
+ .txt(new Date(item.news.publicationDate).toISOString().split('T')[0]!)
117
+ newsElement.ele('news:title').txt(item.news.title)
118
+ }
119
+ }
120
+
121
+ return sitemap.end({ prettyPrint: true })
122
+ }
123
+
124
+ export async function buildSitemap({
125
+ options,
126
+ publicDir,
127
+ }: {
128
+ options: TanStackStartOutputConfig
129
+ publicDir: string
130
+ }) {
131
+ let sitemapOptions = options.sitemap
132
+
133
+ if (!sitemapOptions && options.pages.length) {
134
+ sitemapOptions = { enabled: true, outputPath: 'sitemap.xml' }
135
+ }
136
+
137
+ if (!sitemapOptions?.enabled) {
138
+ throw new Error('Sitemap is not enabled')
139
+ }
140
+
141
+ const { host, outputPath } = sitemapOptions
142
+
143
+ if (!host) {
144
+ if (!options.sitemap) {
145
+ console.info(
146
+ 'Hint: Pages found, but no sitemap host has been set. To enable sitemap generation, set the `sitemap.host` option.',
147
+ )
148
+ return
149
+ }
150
+ throw new Error(
151
+ 'Sitemap host is not set and required to build the sitemap.',
152
+ )
153
+ }
154
+
155
+ if (!outputPath) {
156
+ throw new Error('Sitemap output path is not set')
157
+ }
158
+
159
+ const { pages } = options
160
+
161
+ if (!pages.length) {
162
+ console.log('No pages were found to build the sitemap. Skipping...')
163
+ return
164
+ }
165
+
166
+ console.log('Building Sitemap...')
167
+
168
+ // Build the sitemap data
169
+ const sitemapData = buildSitemapJson(pages, host)
170
+
171
+ // Generate output paths
172
+ const xmlOutputPath = path.join(publicDir, outputPath)
173
+ const pagesOutputPath = path.join(publicDir, 'pages.json')
174
+
175
+ try {
176
+ // Write XML sitemap
177
+ console.log(`Writing sitemap XML at ${xmlOutputPath}`)
178
+ writeFileSync(xmlOutputPath, jsonToXml(sitemapData))
179
+
180
+ // Write pages data for runtime use
181
+ console.log(`Writing pages data at ${pagesOutputPath}`)
182
+ writeFileSync(
183
+ pagesOutputPath,
184
+ JSON.stringify(
185
+ {
186
+ pages,
187
+ host,
188
+ lastBuilt: new Date().toISOString(),
189
+ },
190
+ null,
191
+ 2,
192
+ ),
193
+ )
194
+ } catch (e) {
195
+ console.error(`Unable to write sitemap files`, e)
196
+ }
197
+ }
198
+
199
+ function createXml(elementName: 'urlset' | 'sitemapindex'): XMLBuilder {
200
+ return create({ version: '1.0', encoding: 'UTF-8' })
201
+ .ele(elementName, {
202
+ xmlns: 'https://www.sitemaps.org/schemas/sitemap/0.9',
203
+ })
204
+ .com(`This file was automatically generated by TanStack Start.`)
205
+ }
206
+
207
+ function checkSlash(host: string): string {
208
+ const finalChar = host.slice(-1)
209
+ return finalChar === '/' ? '' : '/'
210
+ }
@@ -5,6 +5,7 @@ import { dirname, resolve } from 'pathe'
5
5
  import { clientDistDir, ssrEntryFile } from '../plugin'
6
6
  import { prerender } from '../prerender'
7
7
  import { VITE_ENVIRONMENT_NAMES } from '../constants'
8
+ import { buildSitemap } from '../build-sitemap'
8
9
  import { devServerPlugin } from './dev-server-plugin'
9
10
  import { buildNitroEnvironment } from './build-nitro'
10
11
  import type { EnvironmentOptions, PluginOption, Rollup } from 'vite'
@@ -132,19 +133,14 @@ export function nitroPlugin(
132
133
  })
133
134
  }
134
135
 
135
- // if (nitroConfig.prerender?.routes?.length && options.sitemap) {
136
- // console.log('Building Sitemap...')
137
- // // sitemap needs to be built after all directories are built
138
- // await buildSitemap({
139
- // host: options.sitemap.host,
140
- // routes: nitroConfig.prerender.routes,
141
- // outputDir: resolve(options.root, 'dist/public'),
142
- // })
143
- // }
144
-
145
- // console.log(
146
- // `\n\n✅ Client and server bundles successfully built.`,
147
- // )
136
+ if (options.pages.length) {
137
+ await buildSitemap({
138
+ options,
139
+ publicDir: nitro.options.output.publicDir,
140
+ })
141
+ }
142
+
143
+ console.log(`\n✅ Client and server bundles successfully built.`)
148
144
  },
149
145
  },
150
146
  }
package/src/prerender.ts CHANGED
@@ -129,15 +129,7 @@ export async function prerender({
129
129
  console.info(`Concurrency: ${concurrency}`)
130
130
  const queue = new Queue({ concurrency })
131
131
 
132
- options.pages.forEach((_page) => {
133
- let page = _page as Page
134
-
135
- if (typeof _page === 'string') {
136
- page = { path: _page }
137
- }
138
-
139
- addCrawlPageTask(page)
140
- })
132
+ options.pages.forEach((page) => addCrawlPageTask(page))
141
133
 
142
134
  await queue.start()
143
135
 
package/src/schema.ts CHANGED
@@ -114,13 +114,12 @@ export function createTanStackStartOptionsSchema(
114
114
  })
115
115
  .optional()
116
116
  .default({}),
117
- pages: z
118
- .array(z.union([z.string(), pageSchema]))
119
- .optional()
120
- .default([]),
121
- sitemap: pagePrerenderOptionsSchema
122
- .extend({
117
+ pages: z.array(pageSchema).optional().default([]),
118
+ sitemap: z
119
+ .object({
120
+ enabled: z.boolean().optional().default(true),
123
121
  host: z.string().optional(),
122
+ outputPath: z.string().optional().default('sitemap.xml'),
124
123
  })
125
124
  .optional(),
126
125
  prerender: z
@@ -1,9 +0,0 @@
1
- export type PagesJson = {
2
- page: string;
3
- lastMod: string;
4
- };
5
- export declare function buildSitemap({ host, routes, outputDir, }: {
6
- host: string;
7
- routes: Array<string | undefined> | (() => Promise<Array<string | undefined>>);
8
- outputDir: string;
9
- }): Promise<void>;
@@ -1,9 +0,0 @@
1
- export type PagesJson = {
2
- page: string;
3
- lastMod: string;
4
- };
5
- export declare function buildSitemap({ host, routes, outputDir, }: {
6
- host: string;
7
- routes: Array<string | undefined> | (() => Promise<Array<string | undefined>>);
8
- outputDir: string;
9
- }): Promise<void>;
@@ -1,79 +0,0 @@
1
- import { writeFileSync } from 'node:fs'
2
- import { resolve } from 'node:path'
3
- import { create } from 'xmlbuilder2'
4
- import type { XMLBuilder } from 'xmlbuilder2/lib/interfaces'
5
-
6
- export type PagesJson = {
7
- page: string
8
- lastMod: string
9
- }
10
-
11
- export async function buildSitemap({
12
- host,
13
- routes,
14
- outputDir,
15
- }: {
16
- host: string
17
- routes: Array<string | undefined> | (() => Promise<Array<string | undefined>>)
18
- outputDir: string
19
- }) {
20
- const routeList: Array<string> = await optionHasRoutes(routes)
21
-
22
- if (routeList.length) {
23
- const slash = checkSlash(host)
24
- const sitemapData: Array<PagesJson> = routeList.map((page: string) => ({
25
- page: `${host}${slash}${page.replace(/^\/+/g, '')}`,
26
- lastMod: new Date().toISOString().split('T')[0]!,
27
- }))
28
-
29
- const sitemap = createXml('urlset')
30
-
31
- for (const item of sitemapData) {
32
- const page = sitemap.ele('url')
33
- page.ele('loc').txt(item.page)
34
- page.ele('lastmod').txt(item.lastMod)
35
- }
36
-
37
- const mapPath = `${resolve(outputDir)}/sitemap.xml`
38
- try {
39
- console.log(`Writing sitemap at ${mapPath}`)
40
- writeFileSync(mapPath, sitemap.end({ prettyPrint: true }))
41
- } catch (e) {
42
- console.error(`Unable to write file at ${mapPath}`, e)
43
- }
44
- }
45
- }
46
-
47
- function createXml(elementName: 'urlset' | 'sitemapindex'): XMLBuilder {
48
- return create({ version: '1.0', encoding: 'UTF-8' })
49
- .ele(elementName, {
50
- xmlns: 'https://www.sitemaps.org/schemas/sitemap/0.9',
51
- })
52
- .com(`This file was automatically generated by Analog.`)
53
- }
54
-
55
- function checkSlash(host: string): string {
56
- const finalChar = host.slice(-1)
57
- return finalChar === '/' ? '' : '/'
58
- }
59
-
60
- async function optionHasRoutes(
61
- routes:
62
- | Array<string | undefined>
63
- | (() => Promise<Array<string | undefined>>),
64
- ): Promise<Array<string>> {
65
- let routeList: Array<string | undefined>
66
-
67
- if (typeof routes === 'function') {
68
- // returns an array or undefined
69
- routeList = await routes()
70
- } else if (Array.isArray(routes)) {
71
- // returns an array of strings
72
- routeList = routes
73
- } else {
74
- // default it to an empty of array
75
- routeList = []
76
- }
77
-
78
- return routeList.filter(Boolean) as Array<string>
79
- }