summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/strange-sheep-film.md40
-rw-r--r--examples/server-islands/astro.config.mjs3
-rw-r--r--packages/astro/e2e/fixtures/server-islands-key/astro.config.mjs3
-rw-r--r--packages/astro/e2e/fixtures/server-islands/astro.config.mjs3
-rw-r--r--packages/astro/src/core/build/index.ts13
-rw-r--r--packages/astro/src/core/build/plugins/plugin-ssr.ts5
-rw-r--r--packages/astro/src/core/config/schema.ts5
-rw-r--r--packages/astro/src/core/create-vite.ts2
-rw-r--r--packages/astro/src/core/errors/errors-data.ts13
-rw-r--r--packages/astro/test/fixtures/server-islands/hybrid/astro.config.mjs3
-rw-r--r--packages/astro/test/fixtures/server-islands/ssr/astro.config.mjs3
-rw-r--r--packages/astro/test/server-islands.test.js18
12 files changed, 79 insertions, 32 deletions
diff --git a/.changeset/strange-sheep-film.md b/.changeset/strange-sheep-film.md
new file mode 100644
index 000000000..dc55ad03a
--- /dev/null
+++ b/.changeset/strange-sheep-film.md
@@ -0,0 +1,40 @@
+---
+'astro': minor
+---
+
+[Server Islands](https://astro.build/blog/future-of-astro-server-islands/) introduced behind an experimental flag in [v4.12.0](https://github.com/withastro/astro/blob/main/packages/astro/CHANGELOG.md#4120) is no longer experimental and is available for general use.
+
+Server islands are Astro's solution for highly cacheable pages of mixed static and dynamic content. They allow you to specify components that should run on the server, allowing the rest of the page to be more aggressively cached, or even generated statically.
+
+Turn any `.astro` component into a server island by adding the `server:defer` directive and optionally, fallback placeholder content. It will be rendered dynamically at runtime outside the context of the rest of the page, allowing you to add longer cache headers for the pages, or even prerender them.
+
+```astro
+---
+import Avatar from '../components/Avatar.astro';
+import GenericUser from '../components/GenericUser.astro';
+---
+<header>
+ <h1>Page Title</h1>
+ <div class="header-right">
+ <Avatar server:defer>
+ <GenericUser slot="fallback" />
+ </Avatar>
+ </div>
+</header>
+```
+
+If you were previously using this feature, please remove the experimental flag from your Astro config:
+
+```diff
+import { defineConfig } from 'astro/config';
+
+export default defineConfig({
+ experimental {
+- serverIslands: true,
+ },
+});
+```
+
+If you have been waiting for stabilization before using server islands, you can now do so.
+
+Please see the [server island documentation](https://docs.astro.build/en/guides/server-islands/) for more about this feature.
diff --git a/examples/server-islands/astro.config.mjs b/examples/server-islands/astro.config.mjs
index c0d6b918a..ef62b5207 100644
--- a/examples/server-islands/astro.config.mjs
+++ b/examples/server-islands/astro.config.mjs
@@ -12,7 +12,4 @@ export default defineConfig({
tailwind({ applyBaseStyles: false })
],
devToolbar: { enabled: false },
- experimental: {
- serverIslands: true,
- }
});
diff --git a/packages/astro/e2e/fixtures/server-islands-key/astro.config.mjs b/packages/astro/e2e/fixtures/server-islands-key/astro.config.mjs
index db1a7b452..b6b0d1b11 100644
--- a/packages/astro/e2e/fixtures/server-islands-key/astro.config.mjs
+++ b/packages/astro/e2e/fixtures/server-islands-key/astro.config.mjs
@@ -6,7 +6,4 @@ export default defineConfig({
output: 'server',
adapter: node({ mode: 'standalone' }),
integrations: [],
- experimental: {
- serverIslands: true,
- }
});
diff --git a/packages/astro/e2e/fixtures/server-islands/astro.config.mjs b/packages/astro/e2e/fixtures/server-islands/astro.config.mjs
index 6b3c2a146..6b3e596c4 100644
--- a/packages/astro/e2e/fixtures/server-islands/astro.config.mjs
+++ b/packages/astro/e2e/fixtures/server-islands/astro.config.mjs
@@ -10,7 +10,4 @@ export default defineConfig({
adapter: nodejs({ mode: 'standalone' }),
integrations: [react(), mdx()],
trailingSlash: process.env.TRAILING_SLASH ?? 'always',
- experimental: {
- serverIslands: true,
- }
});
diff --git a/packages/astro/src/core/build/index.ts b/packages/astro/src/core/build/index.ts
index 440ed6028..c420e85c4 100644
--- a/packages/astro/src/core/build/index.ts
+++ b/packages/astro/src/core/build/index.ts
@@ -210,6 +210,13 @@ class AstroBuilder {
};
const { internals, ssrOutputChunkNames, contentFileNames } = await viteBuild(opts);
+
+ const hasServerIslands = this.settings.serverIslandNameMap.size > 0;
+ // Error if there are server islands but no adapter provided.
+ if(hasServerIslands && this.settings.buildOutput !== 'server') {
+ throw new AstroError(AstroErrorData.NoAdapterInstalledServerIslands);
+ }
+
await staticBuild(opts, internals, ssrOutputChunkNames, contentFileNames);
// Write any additionally generated assets to disk.
@@ -230,11 +237,7 @@ class AstroBuilder {
routes: Object.values(allPages)
.flat()
.map((pageData) => pageData.route)
- .concat(
- this.settings.config.experimental.serverIslands
- ? [getServerIslandRouteData(this.settings.config)]
- : [],
- ),
+ .concat(hasServerIslands ? getServerIslandRouteData(this.settings.config) : []),
logging: this.logger,
cacheManifest: internals.cacheManifestUsed,
});
diff --git a/packages/astro/src/core/build/plugins/plugin-ssr.ts b/packages/astro/src/core/build/plugins/plugin-ssr.ts
index 3ddd1d127..dab617d82 100644
--- a/packages/astro/src/core/build/plugins/plugin-ssr.ts
+++ b/packages/astro/src/core/build/plugins/plugin-ssr.ts
@@ -171,13 +171,10 @@ function generateSSRCode(settings: AstroSettings, adapter: AstroAdapter, middlew
`import * as serverEntrypointModule from '${ADAPTER_VIRTUAL_MODULE_ID}';`,
`import { manifest as defaultManifest } from '${SSR_MANIFEST_VIRTUAL_MODULE_ID}';`,
edgeMiddleware ? `` : `import { onRequest as middleware } from '${middlewareId}';`,
- settings.config.experimental.serverIslands
- ? `import { serverIslandMap } from '${VIRTUAL_ISLAND_MAP_ID}';`
- : '',
+ `import { serverIslandMap } from '${VIRTUAL_ISLAND_MAP_ID}';`,
];
const contents = [
- settings.config.experimental.serverIslands ? '' : `const serverIslandMap = new Map()`,
edgeMiddleware ? `const middleware = (_, next) => next()` : '',
`const _manifest = Object.assign(defaultManifest, {`,
` pageMap,`,
diff --git a/packages/astro/src/core/config/schema.ts b/packages/astro/src/core/config/schema.ts
index 924c10f8f..b89af4f46 100644
--- a/packages/astro/src/core/config/schema.ts
+++ b/packages/astro/src/core/config/schema.ts
@@ -92,7 +92,6 @@ export const ASTRO_CONFIG_DEFAULTS = {
experimental: {
contentCollectionCache: false,
clientPrerender: false,
- serverIslands: false,
contentIntellisense: false,
},
} satisfies AstroUserConfig & { server: { open: boolean } };
@@ -530,10 +529,6 @@ export const AstroConfigSchema = z.object({
.boolean()
.optional()
.default(ASTRO_CONFIG_DEFAULTS.experimental.clientPrerender),
- serverIslands: z
- .boolean()
- .optional()
- .default(ASTRO_CONFIG_DEFAULTS.experimental.serverIslands),
contentIntellisense: z
.boolean()
.optional()
diff --git a/packages/astro/src/core/create-vite.ts b/packages/astro/src/core/create-vite.ts
index e8d9edfe3..eb2765727 100644
--- a/packages/astro/src/core/create-vite.ts
+++ b/packages/astro/src/core/create-vite.ts
@@ -158,7 +158,7 @@ export async function createVite(
astroInternationalization({ settings }),
vitePluginActions({ fs, settings }),
vitePluginUserActions({ settings }),
- settings.config.experimental.serverIslands && vitePluginServerIslands({ settings }),
+ vitePluginServerIslands({ settings }),
astroContainer(),
],
publicDir: fileURLToPath(settings.config.publicDir),
diff --git a/packages/astro/src/core/errors/errors-data.ts b/packages/astro/src/core/errors/errors-data.ts
index 2a4120982..09dc51e0f 100644
--- a/packages/astro/src/core/errors/errors-data.ts
+++ b/packages/astro/src/core/errors/errors-data.ts
@@ -414,6 +414,19 @@ export const AdapterSupportOutputMismatch = {
/**
* @docs
+ * @see
+ * - [Server-side Rendering](https://docs.astro.build/en/guides/server-side-rendering/)
+ * @description
+ * To use server islands, the same constraints exist as for sever-side rendering, so an adapter is needed.
+ */
+export const NoAdapterInstalledServerIslands = {
+ name: 'NoAdapterInstalledServerIslands',
+ title: 'Cannot use Server Islands without an adapter.',
+ message: `Cannot use server islands without an adapter. Please install and configure the appropriate server adapter for your final deployment.`,
+ hint: 'See https://docs.astro.build/en/guides/server-side-rendering/ for more information.',
+} satisfies ErrorData;
+/**
+ * @docs
* @description
* No import statement was found for one of the components. If there is an import statement, make sure you are using the same identifier in both the imports and the component usage.
*/
diff --git a/packages/astro/test/fixtures/server-islands/hybrid/astro.config.mjs b/packages/astro/test/fixtures/server-islands/hybrid/astro.config.mjs
index b01b674f5..c6efdc2a2 100644
--- a/packages/astro/test/fixtures/server-islands/hybrid/astro.config.mjs
+++ b/packages/astro/test/fixtures/server-islands/hybrid/astro.config.mjs
@@ -6,7 +6,4 @@ export default defineConfig({
integrations: [
svelte()
],
- experimental: {
- serverIslands: true,
- }
});
diff --git a/packages/astro/test/fixtures/server-islands/ssr/astro.config.mjs b/packages/astro/test/fixtures/server-islands/ssr/astro.config.mjs
index 79ce4c497..e0fdc9ef2 100644
--- a/packages/astro/test/fixtures/server-islands/ssr/astro.config.mjs
+++ b/packages/astro/test/fixtures/server-islands/ssr/astro.config.mjs
@@ -8,8 +8,5 @@ export default defineConfig({
integrations: [
svelte()
],
- experimental: {
- serverIslands: true,
- }
});
diff --git a/packages/astro/test/server-islands.test.js b/packages/astro/test/server-islands.test.js
index 8806f3511..86956f0d1 100644
--- a/packages/astro/test/server-islands.test.js
+++ b/packages/astro/test/server-islands.test.js
@@ -63,13 +63,14 @@ describe('Server islands', () => {
before(async () => {
fixture = await loadFixture({
root: './fixtures/server-islands/hybrid',
- adapter: testAdapter(),
});
});
describe('build', () => {
before(async () => {
- await fixture.build();
+ await fixture.build({
+ adapter: testAdapter()
+ });
});
it('Omits the island HTML from the static HTML', async () => {
@@ -83,5 +84,18 @@ describe('Server islands', () => {
assert.equal(serverIslandScript.length, 1, 'has the island script');
});
});
+
+ describe('build (no adapter)', () => {
+ it('Errors during the build', async () => {
+ try {
+ await fixture.build({
+ adapter: undefined
+ });
+ assert.equal(true, false, 'should not have succeeded');
+ } catch(err) {
+ assert.equal(err.title, 'Cannot use Server Islands without an adapter.');
+ }
+ });
+ });
});
});