@@ -2,13 +2,59 @@ import type { Plugin } from 'vite';
22import { AstroError , AstroErrorData } from '../core/errors/index.js' ;
33import { SERIALIZED_MANIFEST_ID } from './serialized.js' ;
44import { ASTRO_VITE_ENVIRONMENT_NAMES } from '../core/constants.js' ;
5+ import { fromRoutingStrategy , toFallbackType , toRoutingStrategy } from '../core/app/common.js' ;
6+ import type { AstroSettings } from '../types/astro.js' ;
57
68const VIRTUAL_SERVER_ID = 'astro:config/server' ;
79const RESOLVED_VIRTUAL_SERVER_ID = '\0' + VIRTUAL_SERVER_ID ;
810const VIRTUAL_CLIENT_ID = 'astro:config/client' ;
911const RESOLVED_VIRTUAL_CLIENT_ID = '\0' + VIRTUAL_CLIENT_ID ;
1012
11- export default function virtualModulePlugin ( ) : Plugin {
13+ export default function virtualModulePlugin ( { settings } : { settings : AstroSettings } ) : Plugin {
14+ // Pre-compute the client config values from settings so that astro:config/client
15+ // doesn't need to import from virtual:astro:manifest (which pulls in server-only
16+ // virtual modules like virtual:astro:routes and virtual:astro:pages that are
17+ // restricted to server environments via applyToEnvironment).
18+ const config = settings . config ;
19+
20+ let i18nCode = 'const i18n = undefined;' ;
21+ if ( config . i18n ) {
22+ // Apply the same toRoutingStrategy → fromRoutingStrategy roundtrip that the
23+ // serialized manifest uses, to ensure consistent routing config values.
24+ const strategy = toRoutingStrategy ( config . i18n . routing , config . i18n . domains ) ;
25+ const fallbackType = toFallbackType ( config . i18n . routing ) ;
26+ const routing = fromRoutingStrategy ( strategy , fallbackType ) ;
27+ i18nCode = `const i18n = {
28+ defaultLocale: ${ JSON . stringify ( config . i18n . defaultLocale ) } ,
29+ locales: ${ JSON . stringify ( config . i18n . locales ) } ,
30+ routing: ${ JSON . stringify ( routing ) } ,
31+ fallback: ${ JSON . stringify ( config . i18n . fallback ) }
32+ };` ;
33+ }
34+
35+ let imageCode = 'const image = undefined;' ;
36+ if ( config . image ) {
37+ imageCode = `const image = {
38+ objectFit: ${ JSON . stringify ( config . image . objectFit ) } ,
39+ objectPosition: ${ JSON . stringify ( config . image . objectPosition ) } ,
40+ layout: ${ JSON . stringify ( config . image . layout ) } ,
41+ };` ;
42+ }
43+
44+ const clientConfigCode = `
45+ ${ i18nCode }
46+ ${ imageCode }
47+ const base = ${ JSON . stringify ( config . base ) } ;
48+ const trailingSlash = ${ JSON . stringify ( config . trailingSlash ) } ;
49+ const site = ${ JSON . stringify ( config . site ) } ;
50+ const compressHTML = ${ JSON . stringify ( config . compressHTML ) } ;
51+ const build = {
52+ format: ${ JSON . stringify ( config . build . format ) } ,
53+ };
54+
55+ export { base, i18n, trailingSlash, site, compressHTML, build, image };
56+ ` ;
57+
1258 return {
1359 name : 'astro-manifest-plugin' ,
1460 resolveId : {
@@ -30,41 +76,11 @@ export default function virtualModulePlugin(): Plugin {
3076 } ,
3177 handler ( id ) {
3278 if ( id === RESOLVED_VIRTUAL_CLIENT_ID ) {
33- // There's nothing wrong about using `/client` on the server
34- const code = `
35- import { manifest } from '${ SERIALIZED_MANIFEST_ID } '
36- import { fromRoutingStrategy } from 'astro/app';
37-
38- let i18n = undefined;
39- if (manifest.i18n) {
40- i18n = {
41- defaultLocale: manifest.i18n.defaultLocale,
42- locales: manifest.i18n.locales,
43- routing: fromRoutingStrategy(manifest.i18n.strategy, manifest.i18n.fallbackType),
44- fallback: manifest.i18n.fallback
45- };
46- }
47-
48- let image = undefined;
49- if (manifest.image) {
50- image = {
51- objectFit: manifest.image.objectFit,
52- objectPosition: manifest.image.objectPosition,
53- layout: manifest.image.layout,
54- };
55- }
56-
57- const base = manifest.base;
58- const trailingSlash = manifest.trailingSlash;
59- const site = manifest.site;
60- const compressHTML = manifest.compressHTML;
61- const build = {
62- format: manifest.buildFormat,
63- };
64-
65- export { base, i18n, trailingSlash, site, compressHTML, build, image };
66- ` ;
67- return { code } ;
79+ // astro:config/client inlines values directly from settings instead of
80+ // importing from virtual:astro:manifest to avoid pulling server-only
81+ // virtual modules (virtual:astro:routes, virtual:astro:pages) into the
82+ // client environment where they are not available.
83+ return { code : clientConfigCode } ;
6884 }
6985 if ( id === RESOLVED_VIRTUAL_SERVER_ID ) {
7086 if ( this . environment . name === ASTRO_VITE_ENVIRONMENT_NAMES . client ) {
0 commit comments