diff --git a/.changeset/strong-dogs-boil.md b/.changeset/strong-dogs-boil.md
new file mode 100644
index 000000000..1b9abd69f
--- /dev/null
+++ b/.changeset/strong-dogs-boil.md
@@ -0,0 +1,5 @@
+---
+'@astrojs/svelte': patch
+---
+
+`@astrojs/svelte` integration supports custom svelte compiler options
diff --git a/packages/astro/test/fixtures/svelte-component/astro.config.mjs b/packages/astro/test/fixtures/svelte-component/astro.config.mjs
index dbf6d6b8f..b1aeede15 100644
--- a/packages/astro/test/fixtures/svelte-component/astro.config.mjs
+++ b/packages/astro/test/fixtures/svelte-component/astro.config.mjs
@@ -3,5 +3,7 @@ import svelte from '@astrojs/svelte';
// https://astro.build/config
export default defineConfig({
- integrations: [svelte()],
+ integrations: [svelte({
+ extensions: ['.svelte', '.sve']
+ })],
});
\ No newline at end of file
diff --git a/packages/astro/test/fixtures/svelte-component/src/components/Custom.sve b/packages/astro/test/fixtures/svelte-component/src/components/Custom.sve
new file mode 100644
index 000000000..f61026424
--- /dev/null
+++ b/packages/astro/test/fixtures/svelte-component/src/components/Custom.sve
@@ -0,0 +1,5 @@
+
+
+
{ message }
diff --git a/packages/astro/test/fixtures/svelte-component/src/pages/typescript.astro b/packages/astro/test/fixtures/svelte-component/src/pages/typescript.astro
index d6b416756..2de86df16 100644
--- a/packages/astro/test/fixtures/svelte-component/src/pages/typescript.astro
+++ b/packages/astro/test/fixtures/svelte-component/src/pages/typescript.astro
@@ -1,5 +1,9 @@
---
import TypeScript from '../components/TypeScript.svelte'
+
+// Using a custom extension to verify svelte options
+// in astro.config.mjs are passed properly to the svelte integration
+import Custom from '../components/Custom.sve'
---
@@ -20,6 +24,7 @@ import TypeScript from '../components/TypeScript.svelte'
+
diff --git a/packages/astro/test/svelte-component.test.js b/packages/astro/test/svelte-component.test.js
index 36ba35b51..a68acd924 100644
--- a/packages/astro/test/svelte-component.test.js
+++ b/packages/astro/test/svelte-component.test.js
@@ -22,6 +22,13 @@ describe('Svelte component', () => {
expect($('#svelte-ts').text()).to.equal('Hello, TypeScript');
});
+
+ it('Works with custom Svelte config', async () => {
+ const html = await fixture.readFile('/typescript/index.html');
+ const $ = cheerio.load(html);
+
+ expect($('#svelte-custom-ext').text()).to.equal('Hello, Custom Extensions');
+ });
});
if (isWindows) return;
diff --git a/packages/integrations/svelte/README.md b/packages/integrations/svelte/README.md
index e5bce561a..b0cddafe2 100644
--- a/packages/integrations/svelte/README.md
+++ b/packages/integrations/svelte/README.md
@@ -63,3 +63,31 @@ Also check our [Astro Integration Documentation][astro-integration] for more on
[astro-integration]: https://docs.astro.build/en/guides/integrations-guide/
[astro-ui-frameworks]: https://docs.astro.build/en/core-concepts/framework-components/#using-framework-components
+
+## Options
+
+This integration is powered by `@sveltejs/vite-plugin-svelte`. To customize the Svelte compiler, options can be provided to the integration. See the `@sveltejs/vite-plugin-svelte` [docs](https://github.com/sveltejs/vite-plugin-svelte/blob/HEAD/docs/config.md) for more details.
+
+### Default options
+
+A few of the default options passed to the Svelte compiler are required to build properly for Astro and cannot be overridden.
+
+```js
+const defaultOptions = {
+ emitCss: true,
+ compilerOptions: { dev: isDev, hydratable: true },
+ preprocess: [
+ preprocess({
+ less: true,
+ sass: { renderSync: true },
+ scss: { renderSync: true },
+ stylus: true,
+ typescript: true,
+ }),
+ ],
+};
+```
+
+The `emitCss`, `compilerOptions.dev`, and `compilerOptions.hydratable` cannot be overridden.
+
+Providing your own `preprocess` options **will** override the defaults - make sure to enable the preprocessor flags needed for your project.
\ No newline at end of file
diff --git a/packages/integrations/svelte/src/index.ts b/packages/integrations/svelte/src/index.ts
index f5a3dd945..d12b6d533 100644
--- a/packages/integrations/svelte/src/index.ts
+++ b/packages/integrations/svelte/src/index.ts
@@ -1,6 +1,7 @@
import type { AstroIntegration, AstroRenderer } from 'astro';
import { svelte } from '@sveltejs/vite-plugin-svelte';
import preprocess from 'svelte-preprocess';
+import type { Options } from '@sveltejs/vite-plugin-svelte';
function getRenderer(): AstroRenderer {
return {
@@ -10,38 +11,61 @@ function getRenderer(): AstroRenderer {
};
}
-function getViteConfiguration(isDev: boolean) {
+function getViteConfiguration(isDev: boolean, options?: Options | OptionsCallback) {
+ const defaultOptions = {
+ emitCss: true,
+ compilerOptions: { dev: isDev, hydratable: true },
+ preprocess: [
+ preprocess({
+ less: true,
+ sass: { renderSync: true },
+ scss: { renderSync: true },
+ stylus: true,
+ typescript: true,
+ }),
+ ],
+ };
+
+ let resolvedOptions: Partial;
+
+ if (!options) {
+ resolvedOptions = defaultOptions;
+ } else if (typeof options === 'function') {
+ resolvedOptions = options(defaultOptions);
+ } else {
+ resolvedOptions = {
+ ...options,
+ ...defaultOptions,
+ compilerOptions: {
+ ...options.compilerOptions,
+ // Always use dev and hydratable from defaults
+ ...defaultOptions.compilerOptions,
+ },
+ // Ignore default preprocessor if the user provided their own
+ preprocess: options.preprocess ?? defaultOptions.preprocess,
+ };
+ }
+
return {
optimizeDeps: {
include: ['@astrojs/svelte/client.js', 'svelte', 'svelte/internal'],
exclude: ['@astrojs/svelte/server.js'],
},
plugins: [
- svelte({
- emitCss: true,
- compilerOptions: { dev: isDev, hydratable: true },
- preprocess: [
- preprocess({
- less: true,
- sass: { renderSync: true },
- scss: { renderSync: true },
- stylus: true,
- typescript: true,
- }),
- ],
- }),
+ svelte(resolvedOptions),
],
};
}
-export default function (): AstroIntegration {
+type OptionsCallback = (defaultOptions: Options) => Options;
+export default function (options?: Options | OptionsCallback): AstroIntegration {
return {
name: '@astrojs/svelte',
hooks: {
// Anything that gets returned here is merged into Astro Config
'astro:config:setup': ({ command, updateConfig, addRenderer }) => {
addRenderer(getRenderer());
- updateConfig({ vite: getViteConfiguration(command === 'dev') });
+ updateConfig({ vite: getViteConfiguration(command === 'dev', options) });
},
},
};