Skip to content

Commit

Permalink
Fix server islands with trailingSlash: always (#11529)
Browse files Browse the repository at this point in the history
* Fix server islands with trailingSlash: always

* Fix test missing trailingslash

* Prepend base to the server island URL

* Add tests for base
  • Loading branch information
matthewp authored Jul 26, 2024
1 parent 904f1e5 commit 504c383
Show file tree
Hide file tree
Showing 6 changed files with 17 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/wicked-books-sip.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Fix server islands with trailingSlash: always
2 changes: 2 additions & 0 deletions packages/astro/e2e/fixtures/server-islands/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import nodejs from '@astrojs/node';

// https://astro.build/config
export default defineConfig({
base: '/base',
output: 'hybrid',
adapter: nodejs({ mode: 'standalone' }),
integrations: [react(), mdx()],
trailingSlash: 'always',
experimental: {
serverIslands: true,
}
Expand Down
8 changes: 4 additions & 4 deletions packages/astro/e2e/server-islands.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,23 @@ test.describe('Server islands', () => {
});

test('Load content from the server', async ({ page, astro }) => {
await page.goto(astro.resolveUrl('/'));
await page.goto(astro.resolveUrl('/base/'));
let el = page.locator('#island');

await expect(el, 'element rendered').toBeVisible();
await expect(el, 'should have content').toHaveText('I am an island');
});

test('Can be in an MDX file', async ({ page, astro }) => {
await page.goto(astro.resolveUrl('/mdx'));
await page.goto(astro.resolveUrl('/base/mdx/'));
let el = page.locator('#island');

await expect(el, 'element rendered').toBeVisible();
await expect(el, 'should have content').toHaveText('I am an island');
});

test('Slots are provided back to the server islands', async ({ page, astro }) => {
await page.goto(astro.resolveUrl('/'));
await page.goto(astro.resolveUrl('/base/'));
let el = page.locator('#children');

await expect(el, 'element rendered').toBeVisible();
Expand All @@ -55,7 +55,7 @@ test.describe('Server islands', () => {
});

test('Only one component in prod', async ({ page, astro }) => {
await page.goto(astro.resolveUrl('/'));
await page.goto(astro.resolveUrl('/base/'));

let el = page.locator('#island');

Expand Down
2 changes: 2 additions & 0 deletions packages/astro/src/@types/astro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3324,6 +3324,7 @@ export interface SSRResult {
* Whether the page has failed with a non-recoverable error, or the client disconnected.
*/
cancelled: boolean;
base: string;
styles: Set<SSRElement>;
scripts: Set<SSRElement>;
links: Set<SSRElement>;
Expand Down Expand Up @@ -3352,6 +3353,7 @@ export interface SSRResult {
pathname: string;
cookies: AstroCookies | undefined;
serverIslandNameMap: Map<string, string>;
trailingSlash: AstroConfig['trailingSlash'];
_metadata: SSRMetadata;
}

Expand Down
2 changes: 2 additions & 0 deletions packages/astro/src/core/render-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@ export class RenderContext {
// This object starts here as an empty shell (not yet the result) but then
// calling the render() function will populate the object with scripts, styles, etc.
const result: SSRResult = {
base: manifest.base,
cancelled: false,
clientDirectives,
inlinedScripts,
Expand All @@ -368,6 +369,7 @@ export class RenderContext {
styles,
actionResult,
serverIslandNameMap: manifest.serverIslandNameMap ?? new Map(),
trailingSlash: manifest.trailingSlash,
_metadata: {
hasHydrationScript: false,
rendererSpecificHydrationScripts: new Set(),
Expand Down
3 changes: 2 additions & 1 deletion packages/astro/src/runtime/server/render/server-islands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export function renderServerIsland(
}

const hostId = crypto.randomUUID();
const serverIslandUrl = `${result.base}_server-islands/${componentId}${result.trailingSlash === 'always' ? '/' : ''}`;

destination.write(`<script async type="module" data-island-id="${hostId}">
let componentId = ${safeJsonStringify(componentId)};
Expand All @@ -71,7 +72,7 @@ let data = {
slots: ${safeJsonStringify(renderedSlots)},
};
let response = await fetch('/_server-islands/${componentId}', {
let response = await fetch('${serverIslandUrl}', {
method: 'POST',
body: JSON.stringify(data),
});
Expand Down

0 comments on commit 504c383

Please sign in to comment.