Passing props to the root component of Svelte

Viewed 1374

I understand that like in many front-end frameworks, Svelte allows the developer to separate logic into smaller, reusable component files. In doing so, you can pass props from a parent to a child component.

I would like to know if it is possible to pass props to the root component itself. I am trying to create a model using Svelte, and require some variables to be determined outside of scope of App.svelte (i.e. variables that are assigned at the same level that imports bundle.js)

1 Answers

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'
},
Related