There are 2 main ways to do this
Add data to the global scope
This leverages the global scope of the document to share values between different scripts. It basically boils down to just declaring something in the index.html and then later use it wherever you feel fit.
<!-- index.html -->
<script>
document.myapp = {
name: 'Svelte'
}
</script>
<script defer src="build/bundle.js"></script>
// main.js
const app = new App({
target: document.body,
props: {
name: document.myapp.name
}
});
I use here the main.js because I like to keep all external informal close together in my apps, but in theory you can use document.myapp.name anywhere you want, even as default value for a store
//store.js
export const name = readable(document.myapp.name)
One thing you have to make sure is of course that this object is initialized before the svelte app runs (otherwise it will all just be undefined or even crash)
Export and Call App
The second approach is to not run your App directly in your main.js but instead have another script call it instead.
// main.js
import App from './App.svelte'
export default App
<!-- index.html -->
<head>
<script src='/build/bundle.js'></script>
</head>
<body>
<script>
new app({
target: document.body,
props: {
name: 'from App'
}
})
</script>
</body>
In this case it's important to make sure the script runs after the page has loaded and after the bundle has loaded (here I solved that by adding the script in the body tag and removing the defer from the bundle, there are better ways of doing this I guess)
Another important remark with this approach is that the name of your app is not necessarily what you exported from main.js, it is defined in your rollup.config.js in the output configuration as name (default is app)
//rollup.config.js
output: {
sourcemap: true,
format: 'iife',
name: 'app',
file: 'public/build/bundle.js'
},