Skip to content

Commit

Permalink
Make Astro.url conform to build.format during the build (#4352)
Browse files Browse the repository at this point in the history
* Make Astro.url conform to build.format during the build

* Adding a changeset

* Better implementation

* fix some stuff that tests failed on

* Add docs

* Change to minor

* account for empty path
  • Loading branch information
matthewp committed Aug 25, 2022
1 parent 11ce2b6 commit cd154e4
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/beige-deers-travel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': minor
---

Make Astro.url match the build.format configuration during the build
9 changes: 8 additions & 1 deletion packages/astro/src/@types/astro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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';
};
Expand Down
25 changes: 24 additions & 1 deletion packages/astro/src/core/build/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type {
AstroConfig,
ComponentInstance,
EndpointHandler,
RouteType,
SSRLoadedRenderer,
} from '../../@types/astro';
import type { BuildInternals } from '../../core/build/internal.js';
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/test/astro-get-static-paths.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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/');
});
});
8 changes: 8 additions & 0 deletions packages/astro/test/fixtures/page-format/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "@test/page-format",
"version": "0.0.0",
"private": true,
"dependencies": {
"astro": "workspace:*"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
const another = new URL('./another/', Astro.url);
---
<a id="another" href={another.pathname}></a>
52 changes: 52 additions & 0 deletions packages/astro/test/page-format.test.js
Original file line number Diff line number Diff line change
@@ -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/');
});
});
});
});
6 changes: 6 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit cd154e4

Please sign in to comment.