diff --git a/site/content/tutorial/06-bindings/11-this/app-a/App.svelte b/site/content/tutorial/06-bindings/11-bind-this/app-a/App.svelte
similarity index 100%
rename from site/content/tutorial/06-bindings/11-this/app-a/App.svelte
rename to site/content/tutorial/06-bindings/11-bind-this/app-a/App.svelte
diff --git a/site/content/tutorial/06-bindings/11-this/app-b/App.svelte b/site/content/tutorial/06-bindings/11-bind-this/app-b/App.svelte
similarity index 100%
rename from site/content/tutorial/06-bindings/11-this/app-b/App.svelte
rename to site/content/tutorial/06-bindings/11-bind-this/app-b/App.svelte
diff --git a/site/content/tutorial/06-bindings/11-this/text.md b/site/content/tutorial/06-bindings/11-bind-this/text.md
similarity index 100%
rename from site/content/tutorial/06-bindings/11-this/text.md
rename to site/content/tutorial/06-bindings/11-bind-this/text.md
diff --git a/site/content/tutorial/09-lifecycle/01-onmount/app-a/App.svelte b/site/content/tutorial/09-lifecycle/01-onmount/app-a/App.svelte
new file mode 100644
index 0000000000..e8306d1957
--- /dev/null
+++ b/site/content/tutorial/09-lifecycle/01-onmount/app-a/App.svelte
@@ -0,0 +1,31 @@
+
+
+
+
+
Photo album
+
+
+ {#each photos as photo}
+
+
+ {photo.title}
+
+ {:else}
+
+
loading...
+ {/each}
+
\ No newline at end of file
diff --git a/site/content/tutorial/09-lifecycle/01-onmount/app-b/App.svelte b/site/content/tutorial/09-lifecycle/01-onmount/app-b/App.svelte
new file mode 100644
index 0000000000..1b83727627
--- /dev/null
+++ b/site/content/tutorial/09-lifecycle/01-onmount/app-b/App.svelte
@@ -0,0 +1,38 @@
+
+
+
+
+Photo album
+
+
+ {#each photos as photo}
+
+
+ {photo.title}
+
+ {:else}
+
+
loading...
+ {/each}
+
\ No newline at end of file
diff --git a/site/content/tutorial/09-lifecycle/01-onmount/text.md b/site/content/tutorial/09-lifecycle/01-onmount/text.md
new file mode 100644
index 0000000000..54b385e889
--- /dev/null
+++ b/site/content/tutorial/09-lifecycle/01-onmount/text.md
@@ -0,0 +1,28 @@
+---
+title: onMount
+---
+
+Every component has a *lifecycle* that starts when it is created, and ends when it is destroyed. There are a handful of functions that allow you to run code at key moments during that lifecycle.
+
+The one you'll use most frequently is `onMount`, which runs after the component is first rendered to the DOM. We briefly encountered it [earlier](tutorial/bind-this) when we needed to interact with a `` element after it had been rendered.
+
+We'll add an `onMount` handler that loads some data over the network:
+
+```html
+
+```
+
+> It's recommended to put the `fetch` in `onMount` rather than at the top level of the `
+
+
+ The page has been open for
+ {seconds} {seconds === 1 ? 'second' : 'seconds'}
+
\ No newline at end of file
diff --git a/site/content/tutorial/09-lifecycle/02-ondestroy/app-a/utils.js b/site/content/tutorial/09-lifecycle/02-ondestroy/app-a/utils.js
new file mode 100644
index 0000000000..7b65e75c8c
--- /dev/null
+++ b/site/content/tutorial/09-lifecycle/02-ondestroy/app-a/utils.js
@@ -0,0 +1,5 @@
+import { onDestroy } from 'svelte';
+
+export function onInterval(callback, milliseconds) {
+ // implementation goes here
+}
\ No newline at end of file
diff --git a/site/content/tutorial/09-lifecycle/02-ondestroy/app-b/App.svelte b/site/content/tutorial/09-lifecycle/02-ondestroy/app-b/App.svelte
new file mode 100644
index 0000000000..93a721ef44
--- /dev/null
+++ b/site/content/tutorial/09-lifecycle/02-ondestroy/app-b/App.svelte
@@ -0,0 +1,11 @@
+
+
+
+ The page has been open for
+ {seconds} {seconds === 1 ? 'second' : 'seconds'}
+
\ No newline at end of file
diff --git a/site/content/tutorial/09-lifecycle/02-ondestroy/app-b/utils.js b/site/content/tutorial/09-lifecycle/02-ondestroy/app-b/utils.js
new file mode 100644
index 0000000000..0f75f29e2a
--- /dev/null
+++ b/site/content/tutorial/09-lifecycle/02-ondestroy/app-b/utils.js
@@ -0,0 +1,9 @@
+import { onDestroy } from 'svelte';
+
+export function onInterval(callback, milliseconds) {
+ const interval = setInterval(callback, milliseconds);
+
+ onDestroy(() => {
+ clearInterval(interval);
+ });
+}
\ No newline at end of file
diff --git a/site/content/tutorial/09-lifecycle/02-ondestroy/text.md b/site/content/tutorial/09-lifecycle/02-ondestroy/text.md
new file mode 100644
index 0000000000..647fbaa160
--- /dev/null
+++ b/site/content/tutorial/09-lifecycle/02-ondestroy/text.md
@@ -0,0 +1,43 @@
+---
+title: onDestroy
+---
+
+To run code when your component is destroyed, use `onDestroy`.
+
+For example, we can add a `setInterval` function when our component initialises, and clean it up when it's no longer relevant. Doing so prevents memory leaks.
+
+```html
+
+```
+
+While it's important to call lifecycle functions during the component's initialisation, it doesn't matter *where* you call them from. So if we wanted, we could abstract the interval logic into a helper function in `utils.js`...
+
+```js
+import { onDestroy } from 'svelte';
+
+export function onInterval(callback, milliseconds) {
+ const interval = setInterval(callback, milliseconds);
+
+ onDestroy(() => {
+ clearInterval(interval);
+ });
+}
+```
+
+...and import it into our component:
+
+```html
+
+```
\ No newline at end of file
diff --git a/site/content/tutorial/09-lifecycle/03-update/app-a/App.svelte b/site/content/tutorial/09-lifecycle/03-update/app-a/App.svelte
new file mode 100644
index 0000000000..2081b6ab8c
--- /dev/null
+++ b/site/content/tutorial/09-lifecycle/03-update/app-a/App.svelte
@@ -0,0 +1,106 @@
+
+
+
+
+
+
Eliza
+
+
+ {#each comments as comment}
+
+ {/each}
+
+
+
+
\ No newline at end of file
diff --git a/site/content/tutorial/09-lifecycle/03-update/app-b/App.svelte b/site/content/tutorial/09-lifecycle/03-update/app-b/App.svelte
new file mode 100644
index 0000000000..373b6dcb6a
--- /dev/null
+++ b/site/content/tutorial/09-lifecycle/03-update/app-b/App.svelte
@@ -0,0 +1,106 @@
+
+
+
+
+
+
Eliza
+
+
+ {#each comments as comment}
+
+ {/each}
+
+
+
+
\ No newline at end of file
diff --git a/site/content/tutorial/09-lifecycle/03-update/text.md b/site/content/tutorial/09-lifecycle/03-update/text.md
new file mode 100644
index 0000000000..40e071630a
--- /dev/null
+++ b/site/content/tutorial/09-lifecycle/03-update/text.md
@@ -0,0 +1,24 @@
+---
+title: beforeUpdate and afterUpdate
+---
+
+The `beforeUpdate` function schedules work to happen immediately before the DOM has been updated. `afterUpdate` is its counterpart, used for running code once the DOM is in sync with your data.
+
+Together, they're useful for doing things imperatively that are difficult to achieve in a purely state-driven way, like updating the scroll position of an element.
+
+This [Eliza](https://en.wikipedia.org/wiki/ELIZA) chatbot is annoying to use, because you have to keep scrolling the chat window. Let's fix that.
+
+```js
+let div;
+let autoscroll;
+
+beforeUpdate(() => {
+ autoscroll = div && (div.offsetHeight + div.scrollTop) > (div.scrollHeight - 20);
+});
+
+afterUpdate(() => {
+ if (autoscroll) div.scrollTo(0, div.scrollHeight);
+});
+```
+
+Note that `beforeUpdate` will first run before the component has mounted, so we need to check for the existence of `div` before reading its properties.
\ No newline at end of file
diff --git a/site/content/tutorial/09-lifecycle/meta.json b/site/content/tutorial/09-lifecycle/meta.json
new file mode 100644
index 0000000000..2f833e2a4a
--- /dev/null
+++ b/site/content/tutorial/09-lifecycle/meta.json
@@ -0,0 +1,3 @@
+{
+ "title": "Lifecycle"
+}
\ No newline at end of file
diff --git a/site/content/tutorial/99-todo/99-todo/text.md b/site/content/tutorial/99-todo/99-todo/text.md
index 743f5ab75f..085bfd5afc 100644
--- a/site/content/tutorial/99-todo/99-todo/text.md
+++ b/site/content/tutorial/99-todo/99-todo/text.md
@@ -95,11 +95,10 @@ Maybe lifecycle should go first, since we're using `onMount` in the `this` demo?
## Lifecycle
-* [ ] `onMount`
-* [ ] `onDestroy`
-* [ ] `beforeUpdate`
-* [ ] `afterUpdate`
-* [ ] `tick`
+* [x] `onMount`
+* [x] `onDestroy`
+* [x] `beforeUpdate`
+* [x] `afterUpdate`
* [ ] how lifecycle functions behave in SSR mode?
@@ -154,6 +153,7 @@ Maybe lifecycle should go first, since we're using `onMount` in the `this` demo?
* [ ] Keyed each blocks
* [ ] Debug tags
* [ ] `context="module"`
+* [ ] `tick`
---