The Svelte Application Instance Tutorial

In this Svelte tutorial we learn how the Application Instance controls a Svelte app and how it mounts to the DOM.

Lesson Video

If you prefer to learn visually, you can watch this lesson in video format.

Lesson Project

If you want to follow along with the examples in this lesson, you’ll need a Svelte app that was cloned with degit or scaffolded with Vite

If you already have a generated app from previous lessons, you can use that instead.

The Svelte Application Instance

The Svelte application instance (also known as the Svelte App) is what controls a Svelte application.

The instance is typically linked to an HTML element in the /public/index.html file and any content within that element is controlled by Svelte.

Let’s take a closer look at the app instance and mounting by opening the following files from our project.

  • /src/main.js
  • /public/index.html

We’ll start with the main.js file. If we open it up in the Code Editor, we should see the following.

Example: src/main.js
import App from './App.svelte'

const app = new App({
	target: document.body,
	props: {
		name: 'world'
	}
})

export default app

main.js is the starting point for our application. It imports the root App component ( App.svelte ) and invokes it as a function with a config object of options as its argument.

tip These options are used to mount the app to the page, as well as register any globals that the app or its components need (like the props option).

The first option is target , which specifies where we want to mount the app to the DOM in the index.html file. The default value is the <body> element.

Example: public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset='utf-8'>
	<meta name='viewport' content='width=device-width,initial-scale=1'>

	<title>Svelte app</title>

	<link rel='icon' type='image/png' href='/favicon.png'>
	<link rel='stylesheet' href='/global.css'>
	<link rel='stylesheet' href='/build/bundle.css'>

	<script defer src='/build/bundle.js'></script>
</head>

<body>
<!-- built files will be injected here -->
</body>
</html>

Svelte will inject whatever is in the root App component in between the body tags. From there, Javascript controls the application and is responsible for showing data, changing pages etc.

We typically don’t change where the instance is mounted to because we want Svelte to control our application. That said, the target option takes any valid Javascript querySelector so we can change it if we need to.

As an example, and to better illustrate what’s happening, let’s add two div elements in the body. One of them will have an id="app" .

Example: public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset='utf-8'>
	<meta name='viewport' content='width=device-width,initial-scale=1'>

	<title>Svelte app</title>

	<link rel='icon' type='image/png' href='/favicon.png'>
	<link rel='stylesheet' href='/global.css'>
	<link rel='stylesheet' href='/build/bundle.css'>

	<script defer src='/build/bundle.js'></script>
</head>

<body>
  <!-- Svelte controls everything in this div
       if it's where we mount the app instance -->
  <div id="app"></div>

  <!-- Svelte doesn't control anything in this div -->
  <div>Hello from outside Svelte</div>
</body>
</html>

Now let’s change the target in main.js and specify the element with an id of “app” to be where we mount the instance.

Example: src/main.js
import App from './App.svelte'

const app = new App({
  // Mount the instance to the div
  // with the id="app"
  target: document.querySelector('#app'),
  props: {
    name: 'world'
  }
})

export default app

Let’s run the example in the browser and inspect the page in the browser’s developer tools. It should look similar to the following.

Output: public/index.html
<body>

  <div id="app">
    <h1 class="svelte-1jp219w">Hello, John</h1>
  </div>

  <div>Hello from outside Svelte</div>

</body>

The heading from our root App component has been injected between the div tags with the “app” id. So the instance was successfully mounted to the div .

The second div is outside of Svelte, it can’t control anything in that div because it’s not part of the instance.

As mentioned earlier, we typically mount to the body because we want only Svelte to control the application. So let’s change the index.html file back to use the body element.

Example: public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset='utf-8'>
	<meta name='viewport' content='width=device-width,initial-scale=1'>

	<title>Svelte app</title>

	<link rel='icon' type='image/png' href='/favicon.png'>
	<link rel='stylesheet' href='/global.css'>
	<link rel='stylesheet' href='/build/bundle.css'>

	<script defer src='/build/bundle.js'></script>
</head>

<body>
</body>
</html>

And target the body element in the main.js file. We’ll also remove the props option entirely because we won’t need it for now, and it may cause warnings in the console in the following lessons.

Example: src/main.js
import App from './App.svelte'

const app = new App({
  target: document.body
})

export default app