diff --git a/.changeset/thirty-cheetahs-repeat.md b/.changeset/thirty-cheetahs-repeat.md new file mode 100644 index 0000000000..60c44fe7b0 --- /dev/null +++ b/.changeset/thirty-cheetahs-repeat.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Prefer the `base` config rather than site config for creating URLs for links and scripts. diff --git a/packages/astro/src/core/app/index.ts b/packages/astro/src/core/app/index.ts index d06ff52806..188562e9d7 100644 --- a/packages/astro/src/core/app/index.ts +++ b/packages/astro/src/core/app/index.ts @@ -170,7 +170,7 @@ export class App { const url = new URL(request.url); const manifest = this.#manifest; const info = this.#routeDataToRouteInfo.get(routeData!)!; - const links = createLinkStylesheetElementSet(info.links, manifest.site); + const links = createLinkStylesheetElementSet(info.links); let scripts = new Set(); for (const script of info.scripts) { @@ -182,7 +182,7 @@ export class App { }); } } else { - scripts.add(createModuleScriptElement(script, manifest.site)); + scripts.add(createModuleScriptElement(script)); } } diff --git a/packages/astro/src/core/build/generate.ts b/packages/astro/src/core/build/generate.ts index 039e8283ce..a1e6e64897 100644 --- a/packages/astro/src/core/build/generate.ts +++ b/packages/astro/src/core/build/generate.ts @@ -291,14 +291,8 @@ async function generatePath( debug('build', `Generating: ${pathname}`); - // If a base path was provided, append it to the site URL. This ensures that - // all injected scripts and links are referenced relative to the site and subpath. - const site = - settings.config.base !== '/' - ? joinPaths(settings.config.site?.toString() || 'http://localhost/', settings.config.base) - : settings.config.site; - const links = createLinkStylesheetElementSet(linkIds, site); - const scripts = createModuleScriptsSet(hoistedScripts ? [hoistedScripts] : [], site); + const links = createLinkStylesheetElementSet(linkIds, settings.config.base); + const scripts = createModuleScriptsSet(hoistedScripts ? [hoistedScripts] : [], settings.config.base); if (settings.scripts.some((script) => script.stage === 'page')) { const hashedFilePath = internals.entrySpecifierToBundleMap.get(PAGE_SCRIPT_ID); diff --git a/packages/astro/src/core/build/vite-plugin-hoisted-scripts.ts b/packages/astro/src/core/build/vite-plugin-hoisted-scripts.ts index 23230035cd..7a90f00bbf 100644 --- a/packages/astro/src/core/build/vite-plugin-hoisted-scripts.ts +++ b/packages/astro/src/core/build/vite-plugin-hoisted-scripts.ts @@ -40,7 +40,10 @@ export function vitePluginHoistedScripts( }, async generateBundle(_options, bundle) { - let assetInlineLimit = settings.config.vite?.build?.assetsInlineLimit || 4096; + let assetInlineLimit = 4096; + if(settings.config.vite?.build && settings.config.vite.build.assetsInlineLimit !== undefined) { + assetInlineLimit = settings.config.vite?.build.assetsInlineLimit; + } // Find all page entry points and create a map of the entry point to the hashed hoisted script. // This is used when we render so that we can add the script to the head. diff --git a/packages/astro/src/core/build/vite-plugin-ssr.ts b/packages/astro/src/core/build/vite-plugin-ssr.ts index 33784083cb..8cbc0a1b64 100644 --- a/packages/astro/src/core/build/vite-plugin-ssr.ts +++ b/packages/astro/src/core/build/vite-plugin-ssr.ts @@ -133,17 +133,22 @@ function buildManifest( staticFiles.push(entryModules[PAGE_SCRIPT_ID]); } + const bareBase = removeTrailingForwardSlash(removeLeadingForwardSlash(settings.config.base)); + const joinBase = (pth: string) => (bareBase ? bareBase + '/' + pth : pth); + for (const pageData of eachPageData(internals)) { const scripts: SerializedRouteInfo['scripts'] = []; if (pageData.hoistedScript) { - scripts.unshift(pageData.hoistedScript); + scripts.unshift(Object.assign({}, pageData.hoistedScript, { + value: joinBase(pageData.hoistedScript.value) + })); } if (settings.scripts.some((script) => script.stage === 'page')) { scripts.push({ type: 'external', value: entryModules[PAGE_SCRIPT_ID] }); } - const bareBase = removeTrailingForwardSlash(removeLeadingForwardSlash(settings.config.base)); - const links = sortedCSS(pageData).map((pth) => (bareBase ? bareBase + '/' + pth : pth)); + + const links = sortedCSS(pageData).map((pth) => joinBase(pth)); routes.push({ file: '', diff --git a/packages/astro/src/core/config/schema.ts b/packages/astro/src/core/config/schema.ts index ac70ec337f..30b9f65dd6 100644 --- a/packages/astro/src/core/config/schema.ts +++ b/packages/astro/src/core/config/schema.ts @@ -323,11 +323,23 @@ export function createRelativeSchema(cmd: string, fileProtocolRoot: URL) { config.build.client = new URL('./dist/client/', config.outDir); } const trimmedBase = trimSlashes(config.base); - if (trimmedBase.length && config.trailingSlash === 'never') { - config.base = prependForwardSlash(trimmedBase); - } else { - config.base = prependForwardSlash(appendForwardSlash(trimmedBase)); + + // If there is no base but there is a base for site config, warn. + const sitePathname = config.site && new URL(config.site).pathname; + if(!trimmedBase.length && sitePathname && sitePathname !== '/') { + config.base = sitePathname; + /* eslint-disable no-console */ + console.warn(`The site configuration value includes a pathname of ${sitePathname} but there is no base configuration. + +A future version of Astro will stop using the site pathname when producing and

{origin}

diff --git a/packages/astro/test/ssr-request.test.js b/packages/astro/test/ssr-request.test.js index 8f5c242a44..42817abc52 100644 --- a/packages/astro/test/ssr-request.test.js +++ b/packages/astro/test/ssr-request.test.js @@ -13,6 +13,11 @@ describe('Using Astro.request in SSR', () => { adapter: testAdapter(), output: 'server', base: '/subpath/', + vite: { + build: { + assetsInlineLimit: 0 + } + } }); await fixture.build(); }); @@ -51,6 +56,25 @@ describe('Using Astro.request in SSR', () => { expect(css).to.not.be.an('undefined'); }); + it('script assets have their base prefix', async () => { + const app = await fixture.loadTestAdapterApp(); + let request = new Request('http://example.com/subpath/request'); + let response = await app.render(request); + expect(response.status).to.equal(200); + const html = await response.text(); + const $ = cheerioLoad(html); + + const scriptSrc = $('script').attr('src'); + expect(scriptSrc.startsWith('/subpath/')).to.equal(true); + + request = new Request('http://example.com' + scriptSrc); + response = await app.render(request); + + expect(response.status).to.equal(200); + const js = await response.text(); + expect(js).to.not.be.an('undefined'); + }); + it('assets can be fetched', async () => { const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/subpath/cars.json'); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 51794b2cef..db3b0c9241 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1150,6 +1150,12 @@ importers: dependencies: astro: link:../../.. + packages/astro/test/fixtures/asset-url-base: + specifiers: + astro: workspace:* + dependencies: + astro: link:../../.. + packages/astro/test/fixtures/astro pages: specifiers: astro: workspace:*