summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/beige-deers-travel.md5
-rw-r--r--packages/astro/src/@types/astro.ts9
-rw-r--r--packages/astro/src/core/build/generate.ts25
-rw-r--r--packages/astro/test/astro-get-static-paths.test.js2
-rw-r--r--packages/astro/test/fixtures/page-format/package.json8
-rw-r--r--packages/astro/test/fixtures/page-format/src/pages/nested/page.astro4
-rw-r--r--packages/astro/test/page-format.test.js52
-rw-r--r--pnpm-lock.yaml6
8 files changed, 108 insertions, 3 deletions
diff --git a/.changeset/beige-deers-travel.md b/.changeset/beige-deers-travel.md
new file mode 100644
index 000000000..cdfaa6a41
--- /dev/null
+++ b/.changeset/beige-deers-travel.md
@@ -0,0 +1,5 @@
+---
+'astro': minor
+---
+
+Make Astro.url match the build.format configuration during the build
diff --git a/packages/astro/src/@types/astro.ts b/packages/astro/src/@types/astro.ts
index 19aa85695..ce0c3e4cb 100644
--- a/packages/astro/src/@types/astro.ts
+++ b/packages/astro/src/@types/astro.ts
@@ -428,7 +428,7 @@ export interface AstroUserConfig {
* @name trailingSlash
* @type {('always' | 'never' | 'ignore')}
* @default `'ignore'`
- * @see buildOptions.pageUrlFormat
+ * @see build.format
* @description
*
* Set the route matching behavior of the dev server. Choose from the following options:
@@ -517,6 +517,13 @@ export interface AstroUserConfig {
* }
* }
* ```
+ *
+ * #### Effect on Astro.url
+ * Setting `build.format` controls what `Astro.url` is set to during the build. When it is:
+ * - `directory` - The `Astro.url.pathname` will include a trailing slash to mimic folder behavior; ie `/foo/`.
+ * - `file` - The `Astro.url.pathname` will include `.html`; ie `/foo.html`.
+ *
+ * This means that when you create relative URLs using `new URL('./relative', Astro.url)`, you will get consistent behavior between dev and build.
*/
format?: 'file' | 'directory';
};
diff --git a/packages/astro/src/core/build/generate.ts b/packages/astro/src/core/build/generate.ts
index 5a32122a7..218f1bab3 100644
--- a/packages/astro/src/core/build/generate.ts
+++ b/packages/astro/src/core/build/generate.ts
@@ -8,6 +8,7 @@ import type {
AstroConfig,
ComponentInstance,
EndpointHandler,
+ RouteType,
SSRLoadedRenderer,
} from '../../@types/astro';
import type { BuildInternals } from '../../core/build/internal.js';
@@ -243,6 +244,27 @@ function addPageName(pathname: string, opts: StaticBuildOptions): void {
opts.pageNames.push(pathname.replace(/^\//, ''));
}
+function getUrlForPath(pathname: string, base: string, origin: string, format: 'directory' | 'file', routeType: RouteType): URL {
+ /**
+ * Examples:
+ * pathname: /, /foo
+ * base: /
+ */
+ const ending = format === 'directory' ? '/' : '.html';
+ let buildPathname: string;
+ if(pathname === '/' || pathname === '') {
+ buildPathname = base;
+ } else if(routeType === 'endpoint') {
+ const buildPathRelative = removeLeadingForwardSlash(pathname);
+ buildPathname = base + buildPathRelative;
+ } else {
+ const buildPathRelative = removeTrailingForwardSlash(removeLeadingForwardSlash(pathname)) + ending;
+ buildPathname = base + buildPathRelative;
+ }
+ const url = new URL(buildPathname, origin);
+ return url;
+}
+
async function generatePath(
pathname: string,
opts: StaticBuildOptions,
@@ -290,7 +312,8 @@ async function generatePath(
}
const ssr = opts.astroConfig.output === 'server';
- const url = new URL(opts.astroConfig.base + removeLeadingForwardSlash(pathname), origin);
+ const url = getUrlForPath(pathname, opts.astroConfig.base, origin,
+ opts.astroConfig.build.format, pageData.route.type);
const options: RenderOptions = {
adapterName: undefined,
links,
diff --git a/packages/astro/test/astro-get-static-paths.test.js b/packages/astro/test/astro-get-static-paths.test.js
index 8a0fcca58..80b81140a 100644
--- a/packages/astro/test/astro-get-static-paths.test.js
+++ b/packages/astro/test/astro-get-static-paths.test.js
@@ -169,6 +169,6 @@ describe('getStaticPaths - Astro.url', () => {
const html = await fixture.readFile('/food/tacos/index.html');
const $ = cheerio.load(html);
- expect($('#url').text()).to.equal('/food/tacos');
+ expect($('#url').text()).to.equal('/food/tacos/');
});
});
diff --git a/packages/astro/test/fixtures/page-format/package.json b/packages/astro/test/fixtures/page-format/package.json
new file mode 100644
index 000000000..6352f5bfd
--- /dev/null
+++ b/packages/astro/test/fixtures/page-format/package.json
@@ -0,0 +1,8 @@
+{
+ "name": "@test/page-format",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/astro/test/fixtures/page-format/src/pages/nested/page.astro b/packages/astro/test/fixtures/page-format/src/pages/nested/page.astro
new file mode 100644
index 000000000..eb67508a7
--- /dev/null
+++ b/packages/astro/test/fixtures/page-format/src/pages/nested/page.astro
@@ -0,0 +1,4 @@
+---
+const another = new URL('./another/', Astro.url);
+---
+<a id="another" href={another.pathname}></a>
diff --git a/packages/astro/test/page-format.test.js b/packages/astro/test/page-format.test.js
new file mode 100644
index 000000000..cc31d49d3
--- /dev/null
+++ b/packages/astro/test/page-format.test.js
@@ -0,0 +1,52 @@
+import { expect } from 'chai';
+import * as cheerio from 'cheerio';
+import { loadFixture } from './test-utils.js';
+
+describe('build.format', () => {
+ describe('directory', () => {
+ /** @type {import('./test-utils').Fixture} */
+ let fixture;
+ before(async () => {
+ fixture = await loadFixture({
+ root: './fixtures/page-format/',
+ });
+ });
+
+ describe('Build', () => {
+ before(async () => {
+ await fixture.build();
+ });
+
+ it('relative urls created point to sibling folders', async () => {
+ let html = await fixture.readFile('/nested/page/index.html');
+ let $ = cheerio.load(html);
+ expect($('#another').attr('href')).to.equal('/nested/page/another/');
+ });
+ });
+ });
+
+ describe('file', () => {
+ /** @type {import('./test-utils').Fixture} */
+ let fixture;
+ before(async () => {
+ fixture = await loadFixture({
+ root: './fixtures/page-format/',
+ build: {
+ format: 'file',
+ },
+ });
+ });
+
+ describe('Build', () => {
+ before(async () => {
+ await fixture.build();
+ });
+
+ it('relative urls created point to sibling folders', async () => {
+ let html = await fixture.readFile('/nested/page.html');
+ let $ = cheerio.load(html);
+ expect($('#another').attr('href')).to.equal('/nested/another/');
+ });
+ });
+ });
+});
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 300361cb5..05e7e4ece 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1697,6 +1697,12 @@ importers:
packages/astro/test/fixtures/multiple-renderers/renderers/two:
specifiers: {}
+ packages/astro/test/fixtures/page-format:
+ specifiers:
+ astro: workspace:*
+ dependencies:
+ astro: link:../../..
+
packages/astro/test/fixtures/page-level-styles:
specifiers:
astro: workspace:*