'Svelte/SvelteKit: Dynamic import of components with variable
I want to dynamically import components without importing a specific component. I want to set the component name with a variable, received from the store:
<script lang="ts">
// SVELTE
import { onMount } from 'svelte';
// STORE
import { dynamicComponent } from '$stores/dynamicTitle';
$: $dynamicComponent;
console.log($dynamicComponent)
let renderDynamicComponent
onMount(async () => {
const importValue = (await import(`../../lib/components/Home/DynamicComponents/${String($dynamicComponent)}.svelte`)).default;
// const importValue = (await import(`../../lib/components/Home/DynamicComponents/IntroSectionCustom.svelte`)).default;
renderDynamicComponent = importValue
});
<svelte:component this={renderDynamicComponent}/>
But I get:
Uncaught (in promise) TypeError: Failed to fetch dynamically imported module: http://localhost:3000/src/lib/components/Home/DynamicComponents/Intro-Section-Custom.svelte
I do not understand. From the error, it seems to be the right path ...
Solution 1:[1]
I don't think Svelte + the bundler currently support dynamically generated paths:
let thing = 'Thing';
Thing = (await import(`./${thing}.svelte`)).default; // this won't work
Thing = (await import(`./Thing.svelte`)).default; // this will work
limitation of the bundler.
github issue: https://github.com/sveltejs/svelte/issues/6702
Solution 2:[2]
The Rollup plugin @rollup/plugin-dynamic-import-vars might be of help here. I haven't used it with SvelteKit specifically, but it worked fine with standard Svelte with Vite as bundler.
// Example.svelte
function importLocale(locale) {
return import(`./locales/${locale}.js`);
}
// vite.config.js
import dynamicImportVars from '@rollup/plugin-dynamic-import-vars';
export default (mode) =>
defineConfig({
plugins: [
dynamicImportVars({
include: './src/Example.svelte'
})
]
});
SvelteKit uses Vite behind the scenes, but has its own configuration format. In svelte.config.js
, pass dynamicImportVars()
to the config.vite.plugins
key:
// svelte.config.js
/** @type {import('@sveltejs/kit').Config} */
const config = {
vite: {
plugins: [
dynamicImportVars({
include: './src/Example.svelte'
})
]
}
};
export default config;
Please take note of the limitations mentioned in the README of the Rollup plugin.
Solution 3:[3]
What you're doing does work if not using import vars. When adding an import variable you need make your renderDynamicComponent
identifier reactive. So instead of this:
let renderDynamicComponent
Do this:
$: renderDynamicComponent = null
This will allow svelte:component
to render your imported component with dynamic path variable. This seems to be a special case when using dynamic import vars with Vite.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | |
Solution 3 | vhs |