@ -48,7 +48,7 @@ What happens if we use the new model as a starting point?
## Introducing Sapper
<aside><p>The <ahref="https://sapper.svelte.technology/guide#why-the-name-">name comes from</a> the term for combat engineers, and is also short for Svelte app maker</p></aside>
<aside><p>The <ahref="https://sapper.svelte.technology/docs#why-the-name-">name comes from</a> the term for combat engineers, and is also short for Svelte app maker</p></aside>
[Sapper](https://sapper.svelte.technology) is the answer to that question. **Sapper is a Next.js-style framework that aims to meet the eleven criteria at the top of this article while dramatically reducing the amount of code that gets sent to the browser.** It's implemented as Express-compatible middleware, meaning it's easy to understand and customise.
@ -67,7 +67,7 @@ But size is only part of the story. Svelte apps are also extremely performant an
The biggest drawback for many developers evaluating Sapper would be 'but I like React, and I already know how to use it', which is fair.
If you're in that camp, I'd invite you to at least try alternative frameworks. You might be pleasantly surprised! The [Sapper RealWorld](https://github.com/sveltejs/realworld) implementation totals 1,201 lines of source code, compared to 2,377 for the reference implementation, because you're able to express concepts very concisely using Svelte's template syntax (which [takes all of five minutes to master](https://svelte.technology/guide#template-syntax)). You get [scoped CSS](the-zen-of-just-writing-css), with unused style removal and minification built-in, and you can use preprocessors like LESS if you want. You no longer need to use Babel. SSR is ridiculously fast, because it's just string concatenation. And we recently introduced [svelte/store](https://svelte.technology/guide#state-management), a tiny global store that synchronises state across your component hierarchy with zero boilerplate. The worst that can happen is that you'll end up feeling vindicated!
If you're in that camp, I'd invite you to at least try alternative frameworks. You might be pleasantly surprised! The [Sapper RealWorld](https://github.com/sveltejs/realworld) implementation totals 1,201 lines of source code, compared to 2,377 for the reference implementation, because you're able to express concepts very concisely using Svelte's template syntax (which [takes all of five minutes to master](https://svelte.technology/docs#template-syntax)). You get [scoped CSS](the-zen-of-just-writing-css), with unused style removal and minification built-in, and you can use preprocessors like LESS if you want. You no longer need to use Babel. SSR is ridiculously fast, because it's just string concatenation. And we recently introduced [svelte/store](https://svelte.technology/docs#state-management), a tiny global store that synchronises state across your component hierarchy with zero boilerplate. The worst that can happen is that you'll end up feeling vindicated!
But there are trade-offs nonetheless. Some people have a pathological aversion to any form of 'template language', and maybe that applies to you. JSX proponents will clobber you with the 'it's just JavaScript' mantra, and therein lies React's greatest strength, which is that it is infinitely flexible. That flexibility comes with its own set of trade-offs, but we're not here to discuss those.
@ -86,7 +86,7 @@ If you need to support IE11 and friends, you will need to use a transpiler like
## New lifecycle hooks
In addition to `oncreate` and `ondestroy`, Svelte v2 adds two more [lifecycle hooks](guide#lifecycle-hooks) for responding to state changes:
In addition to `oncreate` and `ondestroy`, Svelte v2 adds two more [lifecycle hooks](docs#lifecycle-hooks) for responding to state changes:
```js
export default {
@ -169,7 +169,7 @@ This change might seem annoying initially, but it's the right move: among other
## event_handler.destroy
If your app has [custom event handlers](guide#custom-event-handlers), they must return an object with a `destroy` method, *not* a `teardown` method (this aligns event handlers with the component API).
If your app has [custom event handlers](docs#custom-event-handlers), they must return an object with a `destroy` method, *not* a `teardown` method (this aligns event handlers with the component API).
@ -176,7 +176,7 @@ You can access the index of the current element with *expression* as *name*, *in
}
```
> By default, if the list `a, b, c` becomes `a, c`, Svelte will *remove* the third block and *change* the second from `b` to `c`, rather than removing `b`. If that's not what you want, use a [keyed each block](guide#keyed-each-blocks).
> By default, if the list `a, b, c` becomes `a, c`, Svelte will *remove* the third block and *change* the second from `b` to `c`, rather than removing `b`. If that's not what you want, use a [keyed each block](docs#keyed-each-blocks).
You can use destructuring patterns on the elements of the array:
@ -237,7 +237,7 @@ If the expression in `{#await expression}` *isn't* a promise, Svelte skips ahead
### Directives
Directives allow you to add special instructions for adding [event handlers](guide#event-handlers), [bindings](guide#bindings), [transitions](guide#transitions) and so on. We'll cover each of those in later stages of this guide – for now, all you need to know is that directives can be identified by the `:` character:
Directives allow you to add special instructions for adding [event handlers](docs#event-handlers), [bindings](docs#bindings), [transitions](docs#transitions) and so on. We'll cover each of those in later stages of this guide – for now, all you need to know is that directives can be identified by the `:` character:
@ -30,7 +30,7 @@ Open the example above in the REPL and inspect the element to see what has happe
This is vastly simpler than achieving the same effect via [Shadow DOM](http://caniuse.com/#search=shadow%20dom) and works everywhere without polyfills.
> Svelte will add a `<style>` tag to the page containing your scoped styles. Dynamically adding styles may be impossible if your site has a [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP). If that's the case, you can use scoped styles by [server-rendering your CSS](guide#rendering-css) and using the `css: false` compiler option (or `--no-css` with the CLI).
> Svelte will add a `<style>` tag to the page containing your scoped styles. Dynamically adding styles may be impossible if your site has a [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP). If that's the case, you can use scoped styles by [server-rendering your CSS](docs#rendering-css) and using the `css: false` compiler option (or `--no-css` with the CLI).
### Cascading rules
@ -95,7 +95,7 @@ For rules *not* to be removed, they must apply to the component's markup. As far
</script>
```
Instead of manually manipulating the DOM, you should always use the `class` attribute (or the [class directive](https://svelte.technology/guide#classes)):
Instead of manually manipulating the DOM, you should always use the `class` attribute (or the [class directive](https://svelte.technology/docs#classes)):
@ -95,7 +95,7 @@ The example above can be achieved with modifiers — no need for a separate even
### Component events
Events are an excellent way for [nested components](guide#nested-components) to communicate with their parents. Let's revisit our earlier example, but turn it into a `<CategoryChooser>` component:
Events are an excellent way for [nested components](docs#nested-components) to communicate with their parents. Let's revisit our earlier example, but turn it into a `<CategoryChooser>` component:
As we've seen, data can be passed down to elements and components with attributes and [props](guide#props). Occasionally, you need to get data back *up*; for that we use bindings.
As we've seen, data can be passed down to elements and components with attributes and [props](docs#props). Occasionally, you need to get data back *up*; for that we use bindings.
[Lifecycle hooks](guide#lifecycle-hooks) will *not* run, with the exception of `onDestroy`, because the component is never 'mounted'.
[Lifecycle hooks](docs#lifecycle-hooks) will *not* run, with the exception of `onDestroy`, because the component is never 'mounted'.
> The SSR compiler will generate a CommonJS module for each of your components – meaning that `import` and `export` statements are converted into their `require` and `module.exports` equivalents. If your components have non-component dependencies, they must also work as CommonJS modules in Node. If you're using ES2015 modules, we recommend the [`esm`](https://github.com/standard-things/esm) module for automatically converting them to CommonJS.
@ -67,7 +67,7 @@ It's easier to show the effect of this than to describe it. Open the following e
### Hydration
If you're using [server-side rendering](guide#server-side-rendering), it's likely that you'll need to create a client-side version of your app *on top of* the server-rendered version. A naive way to do that would involve removing all the existing DOM and rendering the client-side app in its place:
If you're using [server-side rendering](docs#server-side-rendering), it's likely that you'll need to create a client-side version of your app *on top of* the server-rendered version. A naive way to do that would involve removing all the existing DOM and rendering the client-side app in its place:
At first glance `component.on(...)` and `component.fire(...)` aren't particularly useful, but it'll become more so when we learn about [nested components](guide#nested-components) and [component events](guide#component-events).
At first glance `component.on(...)` and `component.fire(...)` aren't particularly useful, but it'll become more so when we learn about [nested components](docs#nested-components) and [component events](docs#component-events).
### component.destroy()
@ -150,6 +150,6 @@ This gives you access to standard options like `target` and `data`, but can also
### component.root
In [nested components](guide#nested-components), each component has a `root` property pointing to the top-level root component – that is, the one instantiated with `new MyComponent({...})`.
In [nested components](docs#nested-components), each component has a `root` property pointing to the top-level root component – that is, the one instantiated with `new MyComponent({...})`.
> Earlier versions of Svelte had a `component.observe(...)` method. This was removed in version 2, in favour of the `onstate` [lifecycle hook](guide#lifecycle-hooks), but is still available via [svelte-extras](https://github.com/sveltejs/svelte-extras).
> Earlier versions of Svelte had a `component.observe(...)` method. This was removed in version 2, in favour of the `onstate` [lifecycle hook](docs#lifecycle-hooks), but is still available via [svelte-extras](https://github.com/sveltejs/svelte-extras).
<!-- TODO explain distincion between logic-less and logic-ful components? -->
<!-- TODO style the <a> so it looks like a link -->
<pstyle="font-size: 1.3rem; color: var(--second)">This component has no props — <ahref="guide#external-properties">declare props with the export keyword</a></p>
<pstyle="font-size: 1.3rem; color: var(--second)">This component has no props — <ahref="docs#external-properties">declare props with the export keyword</a></p>