Merge branch 'master' into issues/3311

pull/4291/head
Simon Holthausen 4 years ago
commit 4242f00105

@ -1,56 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: 'Bug'
assignees: ''
---
## Is this about svelte@next? This project is currently in a pre-release stage and breaking changes may occur at any time. Please do not post any kind of bug reports or questions on GitHub about it.
**Describe the bug**
A clear and concise description of what the bug is.
**Logs**
Please include browser console and server logs around the time this bug occurred.
**To Reproduce**
To help us help you, if you've found a bug please consider the following:
* If you can demonstrate the bug using https://svelte.dev/repl, please do.
* If that's not possible, we recommend creating a small repo that illustrates the problem.
* Reproductions should be small, self-contained, correct examples http://sscce.org.
Occasionally, this won't be possible, and that's fine we still appreciate you raising the issue. But please understand that Svelte is run by unpaid volunteers in their free time, and issues that follow these instructions will get fixed faster.
**Expected behavior**
A clear and concise description of what you expected to happen.
**Stacktraces**
If you have a stack trace to include, we recommend putting inside a `<details>` block for the sake of the thread's readability:
<details>
<summary>Stack trace</summary>
Stack trace goes here...
</details>
**Information about your Svelte project:**
To make your life easier, just run `npx envinfo --system --npmPackages svelte,rollup,webpack --binaries --browsers` and paste the output here.
- Your browser and the version: (e.x. Chrome 52.1, Firefox 48.0, IE 10)
- Your operating system: (e.x. OS X 10, Ubuntu Linux 19.10, Windows XP, etc)
- Svelte version (Please check you can reproduce the issue with the latest release!)
- Whether your project uses Webpack or Rollup
**Severity**
How severe an issue is this bug to you? Is this annoying, blocking some users, blocking an upgrade or blocking your usage of Svelte entirely?
Note: the more honest and specific you are here the more we will take you seriously.
**Additional context**
Add any other context about the problem here.

@ -0,0 +1,50 @@
name: "\U0001F41E Bug report"
description: Report an issue with Svelte
labels: ["triage: bug"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report!
- type: textarea
id: bug-description
attributes:
label: Describe the bug
description: A clear and concise description of what the bug is. If you intend to submit a PR for this issue, tell us in the description. Thanks!
placeholder: Bug description
validations:
required: true
- type: textarea
id: reproduction
attributes:
label: Reproduction
description: Please provide a link to a repo or REPL that can reproduce the problem you ran into. If a report is vague (e.g. just a generic error message) and has no reproduction, it will receive a "need reproduction" label. If no reproduction is provided within a reasonable time-frame, the issue will be closed.
placeholder: Reproduction
validations:
required: true
- type: textarea
id: logs
attributes:
label: Logs
description: "Please include browser console and server logs around the time this bug occurred. Optional if provided reproduction. Please try not to insert an image but copy paste the log text."
render: shell
- type: textarea
id: system-info
attributes:
label: System Info
description: Output of `npx envinfo --system --npmPackages svelte,rollup,webpack --binaries --browsers`
render: shell
placeholder: System, Binaries, Browsers
validations:
required: true
- type: dropdown
id: severity
attributes:
label: Severity
description: Select the severity of this issue
options:
- annoyance
- blocking an upgrade
- blocking all usage of svelte
validations:
required: true

@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Discord Chat
url: https://svelte.dev/chat
about: Ask questions and discuss with other Svelte users in real time.

@ -1,28 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: 'New Feature'
assignees: ''
---
<!--
If you'd like to propose an implementation for a large new feature or change then please create an RFC:
https://github.com/sveltejs/rfcs
-->
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. For example: I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**How important is this feature to you?**
Note: the more honest and specific you are here the more we will take you seriously.
**Additional context**
Add any other context or screenshots about the feature request here.

@ -0,0 +1,42 @@
name: "Feature Request"
description: Request a new Svelte feature
labels: [enhancement]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to request this feature! If your feature request is complex or substantial enough to warrant in-depth discussion, maintainers may close the issue and ask you to open an [RFC](https://github.com/sveltejs/rfcs).
- type: textarea
id: problem
attributes:
label: Describe the problem
description: Please provide a clear and concise description the problem this feature would solve. The more information you can provide here, the better.
placeholder: I'm always frustrated when...
validations:
required: true
- type: textarea
id: solution
attributes:
label: Describe the proposed solution
description: Please provide a clear and concise description of what you would like to happen.
placeholder: I would like to see...
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Alternatives considered
description: "Please provide a clear and concise description of any alternative solutions or features you've considered."
validations:
required: true
- type: dropdown
id: importance
attributes:
label: Importance
description: How important is this feature to you?
options:
- nice to have
- would make my life easier
- i cannot use svelte without it
validations:
required: true

@ -1,12 +0,0 @@
---
name: Questions and help
about: If you think you need help with something related to Svelte
title: ''
labels: 'Question'
assignees: ''
---
This issue tracker is intended to collect bug reports and feature requests.
For help with installation, information on how features work, or questions about specific features of Svelte, please come and join us in the [Svelte Discord](https://svelte.dev/chat), or ask your question on [Stack Overflow](https://stackoverflow.com/questions/tagged/svelte). Any issues open for help requests will be closed to keep from clogging up the issue tracker.

@ -1,5 +1,6 @@
### Before submitting the PR, please make sure you do the following
- [ ] It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
- [ ] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`.
- [ ] This message body should clearly illustrate what problems it solves.
- [ ] Ideally, include a test that fails without this PR but passes with it.

@ -1,44 +1,88 @@
name: CI
on: [push, pull_request]
on:
push:
branches: [ master ]
pull_request:
permissions:
contents: read # to fetch code (actions/checkout)
jobs:
Setup:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macOS-latest]
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
cache: npm
- run: npm install
env:
SKIP_PREPARE: true
- run: npm run build
env:
PUBLISH: true
- name: Upload build assets
id: upload-artifact
uses: actions/upload-artifact@v3
with:
name: build-assets
path: |
index.*
compiler.*
ssr.*
action/
animate/
easing/
internal/
motion/
store/
transition/
types/
Tests:
needs: Setup
runs-on: ${{ matrix.os }}
timeout-minutes: 15
strategy:
matrix:
node-version: [8, 10, 12, 14]
node-version: [8, 10, 12, 14, 16, 18]
os: [ubuntu-latest, windows-latest, macOS-latest]
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- id: npm-cache-dir
run: echo "::set-output name=dir::$(npm config get cache)"
- uses: actions/cache@v2
id: npm-cache
cache: npm
- name: Download build assets
uses: actions/download-artifact@v3
id: download-artifact
with:
path: ${{ steps.npm-cache-dir.outputs.dir }}
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: ${{ runner.os }}-node-
name: build-assets
- name: Get Node version ${{ runner.os }}
run: echo "NODE_VERSION=`node --version`" >> $GITHUB_ENV
if: runner.os != 'Windows'
- name: Get Node version ${{ runner.os }}
run: |
chcp 65001
echo ("NODE_VERSION=$(node --version)") >> $env:GITHUB_ENV
if: runner.os == 'Windows'
- run: npm install --save-dev puppeteer@13
if: ${{ runner.os == 'Linux' && (!startsWith(env.NODE_VERSION, 'v8.') && !startsWith(env.NODE_VERSION, 'v10.')) }}
- run: npm install
- run: npm test
env:
SKIP_PREPARE: true
- run: npm run test:integration
env:
CI: true
Lint:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
- id: npm-cache-dir
run: echo "::set-output name=dir::$(npm config get cache)"
- uses: actions/cache@v2
id: npm-cache
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
path: ${{ steps.npm-cache-dir.outputs.dir }}
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: ${{ runner.os }}-node-
cache: npm
- run: 'npm i && npm run lint'
Unit:
runs-on: ${{ matrix.os }}
@ -47,14 +91,11 @@ jobs:
matrix:
os: [ubuntu-latest, windows-latest, macOS-latest]
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
- id: npm-cache-dir
run: echo "::set-output name=dir::$(npm config get cache)"
- uses: actions/cache@v2
id: npm-cache
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
path: ${{ steps.npm-cache-dir.outputs.dir }}
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: ${{ runner.os }}-node-
- run: 'npm i && npm run test:unit'
cache: npm
- run: npm install
env:
SKIP_PREPARE: true
- run: npm run test:unit

@ -0,0 +1,30 @@
name: Docs
on:
push:
branches:
- master
paths:
- site/content/**
permissions: {}
jobs:
release:
name: Deploy docs
runs-on: ubuntu-latest
steps:
- name: my-app-install token
id: github-app
uses: getsentry/action-github-app-token@v1
with:
app_id: ${{ secrets.GH_APP_ID }}
private_key: ${{ secrets.GH_APP_PRIVATE_KEY }}
- name: run deploy docs workflow
uses: 'sveltejs/action-deploy-docs/dispatch@main'
with:
repo: 'svelte'
branch: 'master'
docs_path: 'site/content'
token: ${{ steps.github-app.outputs.token }}

19
.gitignore vendored

@ -1,6 +1,5 @@
.idea
.DS_Store
.nyc_output
.vscode
node_modules
*.map
@ -8,6 +7,8 @@ node_modules
/compiler.d.ts
/compiler.*js
/index.*js
/ssr.*js
/action
/internal
/store
/easing
@ -15,23 +16,9 @@ node_modules
/transition
/animate
/scratch/
/coverage/
/coverage.lcov
/test/*/samples/_
/yarn-error.log
_actual*.*
_output
/types
/site/cypress/screenshots/
/site/__sapper__/
/site/.env
/site/.sessions
/site/static/svelte-app.json
/site/static/contributors.jpg
/site/static/workers
/site/static/organisations
/site/scripts/svelte-app
/site/scripts/community
/site/src/routes/_contributors.js
/site/src/routes/_components/WhosUsingSvelte.*
.eslintcache

@ -1,7 +1,7 @@
const is_unit_test = process.env.UNIT_TEST;
module.exports = {
file: [
'test/test.ts'
],
file: is_unit_test ? [] : ['test/test.ts'],
require: [
'sucrase/register'
]

@ -0,0 +1,15 @@
module.exports = {
spec: [
'src/**/__test__.ts',
],
require: [
'sucrase/register'
],
recursive: true,
};
// add coverage options when running 'npx c8 mocha'
if (process.env.NODE_V8_COVERAGE) {
module.exports.fullTrace = true;
module.exports.require.push('source-map-support/register');
}

@ -2,10 +2,407 @@
## Unreleased
* Avoid recreating DOM elements during hydration ([#6204](https://github.com/sveltejs/svelte/pull/6204))
* Prefer style directive values over style attribute values ([#7475](https://github.com/sveltejs/svelte/issues/7475))
* Stop intro transition from triggering wrongfully ([#6152](https://github.com/sveltejs/svelte/issues/6152), [#6812](https://github.com/sveltejs/svelte/issues/6812))
* Select `<option>` with `selected` attribute when initial state is `undefined` ([#8361](https://github.com/sveltejs/svelte/issues/8361))
* Add a11y `no-noninteractive-element-to-interactive-role` ([#8167](https://github.com/sveltejs/svelte/pull/8167))
* Account for `bind:group` members being spread across multiple control flow blocks ([#8372](https://github.com/sveltejs/svelte/issues/8372))
* Support literal properties when destructuring objects in the template ([#8357](https://github.com/sveltejs/svelte/pull/8357))
* Prevent derived store callbacks after store is unsubscribed from ([#8364](https://github.com/sveltejs/svelte/issues/8364))
## 3.56.0
* Add `|stopImmediatePropagation` event modifier ([#5085](https://github.com/sveltejs/svelte/issues/5085))
* Add `axis` parameter to `slide` transition ([#6182](https://github.com/sveltejs/svelte/issues/6182))
* Add `readonly` utility to convert `writable` store to readonly ([#6518](https://github.com/sveltejs/svelte/pull/6518))
* Add `readyState` binding for media elements ([#6666](https://github.com/sveltejs/svelte/issues/6666))
* Generate valid automatic component names when the filename contains only special characters ([#7143](https://github.com/sveltejs/svelte/issues/7143))
* Add `naturalWidth` and `naturalHeight` bindings ([#7771](https://github.com/sveltejs/svelte/issues/7771))
* Support `<!-- svelte-ignore ... -->` on components ([#8082](https://github.com/sveltejs/svelte/issues/8082))
* Add a11y warnings:
* `aria-activedescendant-has-tabindex`: checks that elements with `aria-activedescendant` have a `tabindex` ([#8172](https://github.com/sveltejs/svelte/pull/8172))
* `role-supports-aria-props`: checks that the (implicit) element role supports the given aria attributes ([#8195](https://github.com/sveltejs/svelte/pull/8195))
* Add `data-sveltekit-replacestate` and `data-sveltekit-keepfocus` attribute typings ([#8281](https://github.com/sveltejs/svelte/issues/8281))
* Compute node dimensions immediately before crossfading ([#4111](https://github.com/sveltejs/svelte/issues/4111))
* Fix potential infinite invalidate loop with `<svelte:component>` ([#4129](https://github.com/sveltejs/svelte/issues/4129))
* Ensure `bind:offsetHeight` updates initially ([#4233](https://github.com/sveltejs/svelte/issues/4233))
* Don't set selected options if value is unbound or not passed ([#5644](https://github.com/sveltejs/svelte/issues/5644))
* Validate component `:global()` selectors ([#6272](https://github.com/sveltejs/svelte/issues/6272))
* Improve warnings:
* Make `noreferrer` warning less zealous ([#6289](https://github.com/sveltejs/svelte/issues/6289))
* Omit a11y warnings on `<video aria-hidden="true">` ([#7874](https://github.com/sveltejs/svelte/issues/7874))
* Omit a11y warnings on `<svelte:element>` ([#7939](https://github.com/sveltejs/svelte/issues/7939))
* Detect unused empty attribute CSS selectors ([#8042](https://github.com/sveltejs/svelte/issues/8042))
* Omit "no child content" warning on elements with `aria-label` ([#8296](https://github.com/sveltejs/svelte/issues/8296))
* Check value equality for `<input type="search">` and `<input type="url">` ([#7027](https://github.com/sveltejs/svelte/issues/7027))
* Do not select a disabled `<option>` by default when the initial bound value is undefined ([#7041](https://github.com/sveltejs/svelte/issues/7041))
* Handle `{@html}` tags inside `<template>` tags ([#7364](https://github.com/sveltejs/svelte/pull/7364))
* Ensure `afterUpdate` is not called after `onDestroy` ([#7476](https://github.com/sveltejs/svelte/issues/7476))
* Improve handling of `inert` attribute ([#7500](https://github.com/sveltejs/svelte/issues/7500))
* Reduce use of template literals in SSR output for better performance ([#7539](https://github.com/sveltejs/svelte/pull/7539))
* Ensure `<input>` value persists when swapping elements with spread attributes in an `{#each}` block ([#7578](https://github.com/sveltejs/svelte/issues/7578))
* Simplify generated code for reactive statements if dependencies are all static ([#7942](https://github.com/sveltejs/svelte/pull/7942))
* Fix race condition on `<svelte:element>` with transitions ([#7948](https://github.com/sveltejs/svelte/issues/7948))
* Allow assigning to a property of a `const` when destructuring ([#7964](https://github.com/sveltejs/svelte/issues/7964))
* Match browser behavior for decoding malformed HTML entities ([#8026](https://github.com/sveltejs/svelte/issues/8026))
* Ensure `trusted-types` CSP compatibility for Web Components ([#8134](https://github.com/sveltejs/svelte/issues/8134))
* Optimise `<svelte:element>` output code for static tag and static attribute ([#8161](https://github.com/sveltejs/svelte/pull/8161))
* Don't throw when calling unsubscribing from a store twice ([#8186](https://github.com/sveltejs/svelte/pull/8186))
* Clear inputs when `bind:group` value is set to `undefined` ([#8214](https://github.com/sveltejs/svelte/issues/8214))
* Fix handling of nested arrays with keyed `{#each}` containing a non-keyed `{#each}` ([#8282](https://github.com/sveltejs/svelte/issues/8282))
## 3.55.1
* Fix `draw` transition with delay showing a dot at the beginning of the path ([#6816](https://github.com/sveltejs/svelte/issues/6816))
* Fix infinity runtime call stack when propagating bindings ([#7032](https://github.com/sveltejs/svelte/issues/7032))
* Fix static `<svelte:element>` optimization in production mode ([#7937](https://github.com/sveltejs/svelte/issues/7937))
* Fix `svelte-ignore` comment breaking named slot ([#8075](https://github.com/sveltejs/svelte/issues/8075))
* Revert change to prevent running init binding unnecessarily ([#8103](https://github.com/sveltejs/svelte/issues/8103))
* Fix adding duplicate event listeners with `<svelte:element on:event>` ([#8129](https://github.com/sveltejs/svelte/issues/8129))
* Improve detection of promises that are also functions ([#8162](https://github.com/sveltejs/svelte/pull/8162))
* Avoid mutating spread component props during SSR ([#8171](https://github.com/sveltejs/svelte/issues/8171))
* Add missing typing for global `part` attribute ([#8181](https://github.com/sveltejs/svelte/issues/8181))
* Add missing `submitter` property to `on:submit` event type
## 3.55.0
* Add `svelte/elements` for HTML/Svelte typings ([#7649](https://github.com/sveltejs/svelte/pull/7649))
## 3.54.0
* Pass `options.direction` argument to custom transition functions ([#3918](https://github.com/sveltejs/svelte/issues/3918))
* Support fallback a11y WAI-ARIA roles ([#8044](https://github.com/sveltejs/svelte/issues/8044))
* Prevent running init binding unnecessarily ([#5689](https://github.com/sveltejs/svelte/issues/5689), [#6298](https://github.com/sveltejs/svelte/issues/6298))
* Allow updating variables from `@const` declared function ([#7843](https://github.com/sveltejs/svelte/issues/7843))
* Do not emit `a11y-no-noninteractive-tabindex` warning if element has a `tabpanel` ([#8025](https://github.com/sveltejs/svelte/pull/8025))
* Fix escaping SSR'd values in `style:` directive ([#8085](https://github.com/sveltejs/svelte/issues/8085))
## 3.53.1
* Fix exception in `rel=` attribute check with dynamic values ([#7994](https://github.com/sveltejs/svelte/issues/7994))
* Do not emit deprecation warnings for `css` compiler options for now ([#8009](https://github.com/sveltejs/svelte/issues/8009))
* Make compiler run in browser again ([#8010](https://github.com/sveltejs/svelte/issues/8010))
* Upgrade `tslib` ([#8013](https://github.com/sveltejs/svelte/issues/8013))
## 3.53.0
* Check whether `parentNode` exists before removing child ([#6037](https://github.com/sveltejs/svelte/issues/6037))
* Upgrade various dependencies, notably `css-tree` to `2.2.1` ([#7572](https://github.com/sveltejs/svelte/pull/7572), [#7982](https://github.com/sveltejs/svelte/pull/7982))
* Extend `css` compiler option with `'external' | 'injected' | 'none'` settings and deprecate old `true | false` values ([#7914](https://github.com/sveltejs/svelte/pull/7914))
## 3.52.0
* Throw compile-time error when attempting to update `const` variable ([#4895](https://github.com/sveltejs/svelte/issues/4895))
* Warn when using `<a target="_blank">` without `rel="noreferrer"` ([#6188](https://github.com/sveltejs/svelte/issues/6188))
* Support `style:foo|important` modifier ([#7365](https://github.com/sveltejs/svelte/issues/7365))
* Fix hydration regression with `{@html}` and components in `<svelte:head>` ([#7941](https://github.com/sveltejs/svelte/pull/7941))
## 3.51.0
* Add a11y warnings:
* `a11y-click-events-have-key-events`: check if click event is accompanied by key events ([#5073](https://github.com/sveltejs/svelte/pull/5073))
* `a11y-no-noninteractive-tabindex`: check for tabindex on non-interactive elements ([#6693](https://github.com/sveltejs/svelte/pull/6693))
* Warn when two-way binding to `{...rest}` object in `{#each}` block ([#6860](https://github.com/sveltejs/svelte/issues/6860))
* Support `--style-props` on `<svelte:component>` ([#7461](https://github.com/sveltejs/svelte/issues/7461))
* Supports nullish values for component event handlers ([#7568](https://github.com/sveltejs/svelte/issues/7568))
* Supports SVG elements with `<svelte:element>`([#7613](https://github.com/sveltejs/svelte/issues/7613))
* Treat `inert` as boolean attribute ([#7785](https://github.com/sveltejs/svelte/pull/7785))
* Support `--style-props` for SVG components ([#7808](https://github.com/sveltejs/svelte/issues/7808))
* Fix false positive dev warnings about unset props when they are bound ([#4457](https://github.com/sveltejs/svelte/issues/4457))
* Fix hydration with `{@html}` and components in `<svelte:head>` ([#4533](https://github.com/sveltejs/svelte/issues/4533), [#6463](https://github.com/sveltejs/svelte/issues/6463), [#7444](https://github.com/sveltejs/svelte/issues/7444))
* Support scoped style for `<svelte:element>` ([#7443](https://github.com/sveltejs/svelte/issues/7443))
* Improve error message for invalid value for `<svelte:component this={...}>` ([#7550](https://github.com/sveltejs/svelte/issues/7550))
* Improve error message when using logic blocks or tags at invalid location ([#7552](https://github.com/sveltejs/svelte/issues/7552))
* Warn instead of throwing error if `<svelte:element>` is a void tag ([#7566](https://github.com/sveltejs/svelte/issues/7566))
* Supports custom elements in `<svelte:element>` ([#7733](https://github.com/sveltejs/svelte/issues/7733))
* Fix calling component unmount if a component is mounted and then immediately unmounted ([#7817](https://github.com/sveltejs/svelte/issues/7817))
* Do not generate `a11y-role-has-required-aria-props` warning when elements match their semantic role ([#7837](https://github.com/sveltejs/svelte/issues/7837))
* Improve performance of custom element data setting in `<svelte:element>` ([#7869](https://github.com/sveltejs/svelte/pull/7869))
## 3.50.1
* Add all global objects and functions as known globals ([#3805](https://github.com/sveltejs/svelte/issues/3805), [#7223](https://github.com/sveltejs/svelte/issues/7223))
* Fix regression with style manager ([#7828](https://github.com/sveltejs/svelte/issues/7828))
## 3.50.0
* Add a11y warnings:
* `a11y-incorrect-aria-attribute-type`: check ARIA state and property values ([#6978](https://github.com/sveltejs/svelte/pull/6978))
* `a11y-no-abstract-role`: check that ARIA roles are non-abstract ([#6241](https://github.com/sveltejs/svelte/pull/6241))
* `a11y-no-interactive-element-to-noninteractive-role`: check for non-interactive roles used on interactive elements ([#5955](https://github.com/sveltejs/svelte/pull/5955))
* `a11y-role-has-required-aria-props`: check that elements with `role` attribute have all required attributes for that role ([#5852](https://github.com/sveltejs/svelte/pull/5852))
* Add `ComponentEvents` convenience type ([#7702](https://github.com/sveltejs/svelte/pull/7702))
* Add `SveltePreprocessor` utility type ([#7742](https://github.com/sveltejs/svelte/pull/7742))
* Enhance action typings ([#7805](https://github.com/sveltejs/svelte/pull/7805))
* Remove empty stylesheets created from transitions ([#4801](https://github.com/sveltejs/svelte/issues/4801), [#7164](https://github.com/sveltejs/svelte/issues/7164))
* Make `a11y-label-has-associated-control` warning check all descendants for input control ([#5528](https://github.com/sveltejs/svelte/issues/5528))
* Only show lowercase component name warnings for non-HTML/SVG elements ([#5712](https://github.com/sveltejs/svelte/issues/5712))
* Disallow invalid CSS selectors starting with a combinator ([#7643](https://github.com/sveltejs/svelte/issues/7643))
* Use `Node.parentNode` instead of `Node.parentElement` for legacy browser support ([#7723](https://github.com/sveltejs/svelte/issues/7723))
* Handle arrow function on `<slot>` inside `<svelte:fragment>` ([#7485](https://github.com/sveltejs/svelte/issues/7485))
* Improve parsing speed when encountering large blocks of whitespace ([#7675](https://github.com/sveltejs/svelte/issues/7675))
* Fix `class:` directive updates in aborted/restarted transitions ([#7764](https://github.com/sveltejs/svelte/issues/7764))
## 3.49.0
* Improve performance of string escaping during SSR ([#5701](https://github.com/sveltejs/svelte/pull/5701))
* Add `ComponentType` and `ComponentProps` convenience types ([#6770](https://github.com/sveltejs/svelte/pull/6770))
* Add support for CSS `@layer` ([#7504](https://github.com/sveltejs/svelte/issues/7504))
* Export `CompileOptions` from `svelte/compiler` ([#7658](https://github.com/sveltejs/svelte/pull/7658))
* Fix DOM-less components not being properly destroyed ([#7488](https://github.com/sveltejs/svelte/issues/7488))
* Fix `class:` directive updates with `<svelte:element>` ([#7521](https://github.com/sveltejs/svelte/issues/7521), [#7571](https://github.com/sveltejs/svelte/issues/7571))
* Harden attribute escaping during SSR ([#7530](https://github.com/sveltejs/svelte/pull/7530))
## 3.48.0
* Allow creating cancelable custom events with `createEventDispatcher` ([#4623](https://github.com/sveltejs/svelte/issues/4623))
* Support `{@const}` tag in `{#if}` blocks [#7241](https://github.com/sveltejs/svelte/issues/7241)
* Return the context object in `setContext` [#7427](https://github.com/sveltejs/svelte/issues/7427)
* Allow comments inside `{#each}` blocks when using `animate:` ([#3999](https://github.com/sveltejs/svelte/issues/3999))
* Fix `|local` transitions in `{#key}` blocks ([#5950](https://github.com/sveltejs/svelte/issues/5950))
* Support svg namespace for `{@html}` ([#7002](https://github.com/sveltejs/svelte/issues/7002), [#7450](https://github.com/sveltejs/svelte/issues/7450))
* Fix `{@const}` tag not working inside a component when there's no `let:` [#7189](https://github.com/sveltejs/svelte/issues/7189)
* Remove extraneous leading newline inside `<pre>` and `<textarea>` ([#7264](https://github.com/sveltejs/svelte/issues/7264))
* Fix erroneous setting of `textContent` for `<template>` elements ([#7297](https://github.com/sveltejs/svelte/pull/7297))
* Fix value of `let:` bindings not updating in certain cases ([#7440](https://github.com/sveltejs/svelte/issues/7440))
* Fix handling of void tags in `<svelte:element>` ([#7449](https://github.com/sveltejs/svelte/issues/7449))
* Fix handling of boolean attributes in `<svelte:element>` ([#7478](https://github.com/sveltejs/svelte/issues/7478))
* Add special style scoping handling of `[open]` selectors on `<dialog>` elements ([#7495](https://github.com/sveltejs/svelte/issues/7494))
## 3.47.0
* Add support for dynamic elements through `<svelte:element>` ([#2324](https://github.com/sveltejs/svelte/issues/2324))
* Miscellaneous variable context fixes in `{@const}` ([#7222](https://github.com/sveltejs/svelte/pull/7222))
* Fix `{#key}` block not being reactive when the key variable is not otherwise used ([#7408](https://github.com/sveltejs/svelte/issues/7408))
* Add `Symbol` as a known global ([#7418](https://github.com/sveltejs/svelte/issues/7418))
## 3.46.6
* Actually include action TypeScript interface in published package ([#7407](https://github.com/sveltejs/svelte/pull/7407))
## 3.46.5
* Add TypeScript interfaces for typing actions ([#6538](https://github.com/sveltejs/svelte/issues/6538))
* Do not generate `unused-export-let` warning inside `<script context="module">` blocks ([#7055](https://github.com/sveltejs/svelte/issues/7055))
* Do not collapse whitespace-only CSS vars ([#7152](https://github.com/sveltejs/svelte/issues/7152))
* Add `aria-description` to the list of allowed ARIA attributes ([#7301](https://github.com/sveltejs/svelte/issues/7301))
* Fix attribute escaping during SSR ([#7327](https://github.com/sveltejs/svelte/issues/7327))
* Prevent `.innerHTML` optimization from being used when `style:` directive is present ([#7386](https://github.com/sveltejs/svelte/issues/7386))
## 3.46.4
* Avoid `maximum call stack size exceeded` errors on large components ([#4694](https://github.com/sveltejs/svelte/issues/4694))
* Preserve leading space with `preserveWhitespace: true` ([#4731](https://github.com/sveltejs/svelte/issues/4731))
* Preserve leading space in `<pre>` tags ([#6437](https://github.com/sveltejs/svelte/issues/6437))
* Improve error message when trying to use `style:` directives on inline components ([#7177](https://github.com/sveltejs/svelte/issues/7177))
* Add `FormData` as a known global ([#7199](https://github.com/sveltejs/svelte/pull/7199))
* Mark `css`/`instance`/`module` AST properties as optional in types ([#7204](https://github.com/sveltejs/svelte/pull/7204))
## 3.46.3
* Ignore whitespace in `{#each}` blocks when containing elements with `animate:` ([#5477](https://github.com/sveltejs/svelte/pull/5477))
* Throw compiler error when variable in `context="instance"` collides with import in `context="module"` ([#7090](https://github.com/sveltejs/svelte/issues/7090))
* Fix compiler crash when `{@const}` contains arrow functions ([#7134](https://github.com/sveltejs/svelte/issues/7134))
## 3.46.2
* Export `FlipParams` interface from `svelte/animate` ([#7103](https://github.com/sveltejs/svelte/issues/7103))
* Fix `style:` directive reactivity inside `{#each}` block ([#7136](https://github.com/sveltejs/svelte/issues/7136))
## 3.46.1
* Handle `style:kebab-case` directives ([#7122](https://github.com/sveltejs/svelte/issues/7122))
* Improve AST produced for `style:` directives ([#7127](https://github.com/sveltejs/svelte/pull/7127))
## 3.46.0
* Implement `{@const}` tag ([RFC #33](https://github.com/sveltejs/rfcs/pull/33), [#6413](https://github.com/sveltejs/svelte/pull/6413))
* Implement `style:` directive ([RFC #42](https://github.com/sveltejs/rfcs/pull/42), [#5923](https://github.com/sveltejs/svelte/pull/5923))
* Fix style manager conflicts when using multiple Svelte instances ([#7026](https://github.com/sveltejs/svelte/issues/7026))
* Fix hydration when using `{@html}` ([#7115](https://github.com/sveltejs/svelte/issues/7115))
## 3.45.0
* Fix non-boolean attribute rendering in SSR to render truthy values as-is ([#6121](https://github.com/sveltejs/svelte/issues/6121))
* Fix binding to a member expression also invalidating the member property ([#6921](https://github.com/sveltejs/svelte/issues/6921))
* Fix default values in `{#each}`/etc. destructurings not being considered references for the purposes of compiler warnings ([#6964](https://github.com/sveltejs/svelte/issues/6964))
* Fix `{:else if}` value incorrectly being cached ([#7043](https://github.com/sveltejs/svelte/pull/7043))
* Add `a11y-no-redundant-roles` warning ([#7067](https://github.com/sveltejs/svelte/pull/7067))
* Fix code generation error with arrow functions whose bodies are object destructuring assignments ([#7087](https://github.com/sveltejs/svelte/issues/7087))
## 3.44.3
* Fix `bind:this` binding inside `onMount` for manually instantiated component ([#6760](https://github.com/sveltejs/svelte/issues/6760))
* Prevent cursor jumps with one-way binding for other `type="text"`-like `<input>`s ([#6941](https://github.com/sveltejs/svelte/pull/6941))
* Exclude `async` loops from `loopGuardTimeout` ([#6945](https://github.com/sveltejs/svelte/issues/6945))
## 3.44.2
* Fix overly restrictive preprocessor types ([#6904](https://github.com/sveltejs/svelte/pull/6904))
* More specific typing for crossfade function - returns a tuple, not an array ([#6926](https://github.com/sveltejs/svelte/issues/6926))
* Add `URLSearchParams` as a known global ([#6938](https://github.com/sveltejs/svelte/pull/6938))
* Add `types` field to `exports` map ([#6939](https://github.com/sveltejs/svelte/issues/6939))
## 3.44.1
* Fix code generation when a multi-line `return` statement contains comments ([code-red#36](https://github.com/Rich-Harris/code-red/issues/36))
* Fix code generation when `for`/`if`/`while` statements have empty bodies ([#6884](https://github.com/sveltejs/svelte/issues/6884))
## 3.44.0
* Add `enableSourcemap` compiler option ([#6835](https://github.com/sveltejs/svelte/pull/6835))
## 3.43.2
* Fix regression where user-specified `import`s were not rewritten according to the `sveltePath` option ([#6834](https://github.com/sveltejs/svelte/issues/6834))
## 3.43.1
* Prevent a rejecting promise used in `{#await}` during SSR from appearing as an unhandled rejection ([#6789](https://github.com/sveltejs/svelte/issues/6789))
## 3.43.0
* Use export map to expose no-op versions of lifecycle functions for SSR ([#6743](https://github.com/sveltejs/svelte/pull/6743))
* Prefer `context` passed to component constructor, even when running synchronously in another component ([#6753](https://github.com/sveltejs/svelte/issues/6753))
* Handle preprocessors that return empty sourcemaps ([#6757](https://github.com/sveltejs/svelte/pull/6757))
## 3.42.6
* Hide private preprocess typings ([#6622](https://github.com/sveltejs/svelte/issues/6622))
* Fix reactive function in `{:else if}` expression not being properly re-run ([#6727](https://github.com/sveltejs/svelte/pull/6727))
## 3.42.5
* In `draw` transition, account for `stroke-linecap` in determining length ([#4540](https://github.com/sveltejs/svelte/issues/4540))
* Fix regression with destructuring assignments with default values ([#6699](https://github.com/sveltejs/svelte/issues/6699))
## 3.42.4
* Only apply optimized `src` attribute handling when in an `html` namespace ([#6575](https://github.com/sveltejs/svelte/issues/6575))
* Fix styles for transitions and animations being attached to the wrong `document` in `<iframe>`s ([#6637](https://github.com/sveltejs/svelte/issues/6637))
* Fix `<select>` with a `{...spread}` attribute that didn't provide a `value` key getting its value improperly unset ([#6675](https://github.com/sveltejs/svelte/issues/6675))
## 3.42.3
* Add `BigInt` as a known global ([#6671](https://github.com/sveltejs/svelte/pull/6671))
* Fix regression where `onDestroy` in `svelte/ssr` was improperly a no-op ([#6676](https://github.com/sveltejs/svelte/issues/6676))
## 3.42.2
* Collapse whitespace in `class` and `style` attributes ([#6004](https://github.com/sveltejs/svelte/issues/6004))
* Deselect all `<option>`s in a `<select>` where the bound `value` doesn't match any of them ([#6126](https://github.com/sveltejs/svelte/issues/6126))
* In hydrated components, only rely on helpers for creating the types of elements present in the component ([#6555](https://github.com/sveltejs/svelte/issues/6555))
* Add `HTMLElement` and `SVGElement` as known globals ([#6643](https://github.com/sveltejs/svelte/issues/6643))
* Account for scaling in `flip` animations ([#6657](https://github.com/sveltejs/svelte/issues/6657))
## 3.42.1
* Fix regression with reordering keyed `{#each}` blocks when compiling with hydration enabled ([#6561](https://github.com/sveltejs/svelte/issues/6561))
## 3.42.0
* Allow `use:actions` to be used on `<svelte:body>` ([#3163](https://github.com/sveltejs/svelte/issues/3163))
* Improve parser errors for certain invalid components ([#6259](https://github.com/sveltejs/svelte/issues/6259), [#6288](https://github.com/sveltejs/svelte/issues/6288))
* Fix paths in generator JS sourcemaps to be relative ([#6598](https://github.com/sveltejs/svelte/pull/6598))
* Fix overzealous warnings about `context="module"` variables not being reactive ([#6606](https://github.com/sveltejs/svelte/issues/6606))
## 3.41.0
* Support `export { ... } from` syntax in components ([#2214](https://github.com/sveltejs/svelte/issues/2214))
* Support `export let { ... } =` syntax in components ([#5612](https://github.com/sveltejs/svelte/issues/5612))
* Support `{#await ... then/catch}` without a variable for the resolved/rejected value ([#6270](https://github.com/sveltejs/svelte/issues/6270))
## 3.40.3
* Fix `<slot>` data when a transition is cancelled before completing ([#5394](https://github.com/sveltejs/svelte/issues/5394))
* Fix destructuring into variables beginning with `$` so that they result in store updates ([#5653](https://github.com/sveltejs/svelte/issues/5653))
* Fix `in:` transition configuration not properly updating when it's changed after its initial creation ([#6505](https://github.com/sveltejs/svelte/issues/6505))
* Fix applying `:global()` for `>` selector combinator ([#6550](https://github.com/sveltejs/svelte/issues/6550))
* Fix mounting component at detached DOM node ([#6567](https://github.com/sveltejs/svelte/issues/6567))
## 3.40.2
* Fix dynamic `autofocus={...}` attribute handling ([#4995](https://github.com/sveltejs/svelte/issues/4995))
* Add filename to combined source map if needed ([#6089](https://github.com/sveltejs/svelte/pull/6089))
* In AST, parse empty attribute values as an empty string ([#6286](https://github.com/sveltejs/svelte/issues/6286))
* Fix tracking whether transition has started ([#6399](https://github.com/sveltejs/svelte/pull/6399))
* Fix incorrect scoping of `:global()` selectors ([#6550](https://github.com/sveltejs/svelte/issues/6550))
## 3.40.1
* Fix store reactivity regression when using reactive statements ([#6557](https://github.com/sveltejs/svelte/issues/6557))
## 3.40.0
* Support rendering a component in a shadow DOM ([#5869](https://github.com/sveltejs/svelte/issues/5869))
* Fix `:root` selector being erroneously scoped to component ([#4767](https://github.com/sveltejs/svelte/issues/4767))
* Fix `.end` in AST for expressions inside attributes ([#6258](https://github.com/sveltejs/svelte/issues/6258))
* Fix one-way `<select>` binding when it has a spread attribute ([#6433](https://github.com/sveltejs/svelte/issues/6433))
* Various hydration improvements and fixes ([#6449](https://github.com/sveltejs/svelte/pull/6449))
* Use smaller versions of internal helpers when compiling without hydration support ([#6462](https://github.com/sveltejs/svelte/issues/6462))
* Fix two-way binding of values when updating through synchronous component accessors ([#6502](https://github.com/sveltejs/svelte/issues/6502))
## 3.39.0
* Support `bind:group` in SSR ([#4621](https://github.com/sveltejs/svelte/pull/4621))
* Add a11y warning `a11y-mouse-events-have-key-events` which checks that `mouseover`/`mouseout` are accompanied by `focus`/`blur` event handlers ([#5938](https://github.com/sveltejs/svelte/pull/5938))
* Make it possible to silence more warnings ([#5954](https://github.com/sveltejs/svelte/issues/5954))
* Add `|trusted` event modifier ([#6137](https://github.com/sveltejs/svelte/issues/6137))
* Add `varsReport` compiler option to include all variables reference in the component in the `variables` report ([#6192](https://github.com/sveltejs/svelte/pull/6192))
* Add `errorMode` compiler option to try to continue compiling when an error is detected ([#6194](https://github.com/sveltejs/svelte/pull/6194))
* Expose `svelte/ssr` which exports lifecycle methods as no-ops ([#6416](https://github.com/sveltejs/svelte/pull/6416))
* Add `getAllContexts` ([#6447](https://github.com/sveltejs/svelte/issues/6447))
* Throw proper error for `export default function() {}` and `export default class {}` rather than crashing the compiler ([#3275](https://github.com/sveltejs/svelte/issues/3275))
* Fix SSR rendering of falsy `input` values ([#4551](https://github.com/sveltejs/svelte/issues/4551))
* Fix `preserveComments` in SSR mode ([#4730](https://github.com/sveltejs/svelte/issues/4730))
* Do not warn if `context="module"` variables are not the only dependencies in reactive statements ([#5954](https://github.com/sveltejs/svelte/issues/5954))
* Stop checking `a11y-media-has-caption` a11y warning on `<audio>` elements ([#6054](https://github.com/sveltejs/svelte/issues/6054))
* Fix erroneous "unknown prop" warning when using slot on a component ([#6065](https://github.com/sveltejs/svelte/pull/6065))
* Add sourcemaps to all HTML elements ([#6092](https://github.com/sveltejs/svelte/issues/6092))
* Relax `derived` function signature ([#6178](https://github.com/sveltejs/svelte/issues/6178))
* Throw compiler error when passing empty directive names ([#6299](https://github.com/sveltejs/svelte/issues/6299))
* Fix compiler error when using `:where()` inside `:global()` ([#6434](https://github.com/sveltejs/svelte/issues/6434))
* Fix ordering of elements in keyed `{#each}` ([#6444](https://github.com/sveltejs/svelte/issues/6444))
* Remove deprecated a11y warning `a11y-no-onchange warning` ([#6457](https://github.com/sveltejs/svelte/issues/6457))
* Fix `:global()` with pseudo element not being seen as global ([#6468](https://github.com/sveltejs/svelte/issues/6468))
* Allow `:global()` to contain multiple selectors when it is not part of a larger selector ([#6477](https://github.com/sveltejs/svelte/issues/6477))
* Make `<script>` and `<style>` end tag parsing more robust ([#6511](https://github.com/sveltejs/svelte/pull/6511))
## 3.38.3
* Speed up hydration by reducing amount of element reorderings ([#4308](https://github.com/sveltejs/svelte/issues/4308))
* Fix escaping attribute values when using a spread in SSR ([#5756](https://github.com/sveltejs/svelte/issues/5756))
* Throw compiler error when `:global()` contains multiple selectors ([#5907](https://github.com/sveltejs/svelte/issues/5907))
* Give explicit error rather than crashing when an attribute shorthand `{}` is empty ([#6086](https://github.com/sveltejs/svelte/issues/6086))
* Make `<textarea>` end tag parsing more robust ([#6276](https://github.com/sveltejs/svelte/issues/6276))
* Fix `:global(...):some-pseudoclass` selectors not being seen as global ([#6306](https://github.com/sveltejs/svelte/issues/6306))
* Fix type signatures of `writable` and `readable` so it's possible to call them without arguments ([#6291](https://github.com/sveltejs/svelte/issues/6291), [#6345](https://github.com/sveltejs/svelte/issues/6345))
* Preserve `this` in bubbled events ([#6310](https://github.com/sveltejs/svelte/issues/6310))
* Fix slot props not updating when transition is aborted ([#6386](https://github.com/sveltejs/svelte/issues/6386))
* Fix generic props relationship in `SvelteComponentTyped` ([#6400](https://github.com/sveltejs/svelte/pull/6400))
## 3.38.2
* Revert hydration optimisation for the time being ([#6279](https://github.com/sveltejs/svelte/issues/6279))
## 3.38.1
* Fix hydration regression ([#6274](https://github.com/sveltejs/svelte/issues/6274))
## 3.38.0
* Avoid recreating DOM elements during hydration ([#1067](https://github.com/sveltejs/svelte/issues/1067))
* Support passing CSS custom properties to component ([#5628](https://github.com/sveltejs/svelte/issues/5628))
* Support `:global()` as part of compound CSS selectors ([#6222](https://github.com/sveltejs/svelte/issues/6222))
* Fix updating `<slot>` contents when there's an aborted transition ([#3542](https://github.com/sveltejs/svelte/issues/3542))
* Fix setting boolean attributes on custom elements ([#5951](https://github.com/sveltejs/svelte/issues/5951))
* Add missing function overload for `derived` to allow explicitly setting an initial value for non-async derived stores ([#6172](https://github.com/sveltejs/svelte/pull/6172))
* Pass full markup source to script/style preprocessors ([#6169](https://github.com/sveltejs/svelte/pull/6169))
* Add "context" typing to SvelteComponent constructor options ([#6236](https://github.com/sveltejs/svelte/pull/6236))
* Fix dynamic `href` values erroneously triggering a11y warnings ([#5990](https://github.com/sveltejs/svelte/issues/5990))
* Fix scope leak when updating an `{#await}` block ([#6173](https://github.com/sveltejs/svelte/issues/6173))
* Pass full markup source to `script`/`style` preprocessors ([#6169](https://github.com/sveltejs/svelte/pull/6169))
* Fix `crossfade` types to mark `fallback` as optional ([#6201](https://github.com/sveltejs/svelte/pull/6201))
* Add missing "context" typing to `SvelteComponent` constructor options ([#6236](https://github.com/sveltejs/svelte/pull/6236))
* Don't automatically switch to `svg` namespace when in `foreign` namespace ([#6257](https://github.com/sveltejs/svelte/issues/6257))
## 3.37.0
@ -692,7 +1089,7 @@ Also:
## 3.5.1
* Accommodate webpack idiosyncracies
* Accommodate webpack idiosyncrasies
## 3.5.0
@ -894,7 +1291,7 @@ Also:
## 2.12.0
* Initialise actions on mount rather than hydrate ([#1653](https://github.com/sveltejs/svelte/pull/1653))
* Allow non-existent components to be destroyed ([#1677](https://github.com/sveltejs/svelte/pull/1677))
* Allow nonexistent components to be destroyed ([#1677](https://github.com/sveltejs/svelte/pull/1677))
* Pass AMD ID from CLI correctly ([#1672](https://github.com/sveltejs/svelte/pull/1672))
* Minor AST tweaks ([#1673](https://github.com/sveltejs/svelte/pull/1673), [#1674](https://github.com/sveltejs/svelte/pull/1674))
* Reduce code duplication in component initialisation ([#1670](https://github.com/sveltejs/svelte/pull/1670))
@ -1904,7 +2301,7 @@ Also:
## 1.10.3
* Prevent `'</script>'` string occurence breaking pages ([#349](https://github.com/sveltejs/svelte/pull/349))
* Prevent `'</script>'` string occurrence breaking pages ([#349](https://github.com/sveltejs/svelte/pull/349))
* Allow reference to whitelisted globals without properties ([#333](https://github.com/sveltejs/svelte/pull/333))
* Don't remove `&nbsp;` incorrectly ([#348](https://github.com/sveltejs/svelte/issues/348))
* `let` -> `var` in `addCss` block ([#351](https://github.com/sveltejs/svelte/pull/351))

@ -0,0 +1,3 @@
This repository is governed by the Svelte Code of Conduct.
https://github.com/sveltejs/community/blob/main/CODE_OF_CONDUCT.md

@ -11,11 +11,11 @@ The [Open Source Guides](https://opensource.guide/) website has a collection of
There are many ways to contribute to Svelte, and many of them do not involve writing any code. Here's a few ideas to get started:
- Simply start using Svelte. Go through the [Getting Started](https://svelte.dev/blog/the-easiest-way-to-get-started) guide. Does everything work as expected? If not, we're always looking for improvements. Let us know by [opening an issue](#reporting-new-issues).
- Look through the [open issues](https://github.com/sveltejs/svelte/issues). Provide workarounds, ask for clarification, or suggest labels. Help [triage issues](#triaging-issues-and-pull-requests).
- If you find an issue you would like to fix, [open a pull request](#your-first-pull-request).
- Simply start using Svelte. Go through the [Getting Started](https://svelte.dev/docs#getting-started) guide. Does everything work as expected? If not, we're always looking for improvements. Let us know by [opening an issue](#reporting-new-issues).
- Look through the [open issues](https://github.com/sveltejs/svelte/issues). A good starting point would be issues tagged [good first issue](https://github.com/sveltejs/svelte/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22). Provide workarounds, ask for clarification, or suggest labels. Help [triage issues](#triaging-issues-and-pull-requests).
- If you find an issue you would like to fix, [open a pull request](#pull-requests).
- Read through our [tutorials](https://svelte.dev/tutorial/basics). If you find anything that is confusing or can be improved, you can make edits by clicking "Edit this chapter" at the bottom left of the tutorial page.
- Take a look at the [features requested](https://github.com/sveltejs/svelte/labels/enhancement) by others in the community and consider opening a pull request if you see something you want to work on.
- Take a look at the [features requested](https://github.com/sveltejs/svelte/labels/feature%20request) by others in the community and consider opening a pull request if you see something you want to work on.
Contributions are very welcome. If you think you need help planning your contribution, please ping us on Discord at [svelte.dev/chat](https://svelte.dev/chat) and let us know you are looking for a bit of help.
@ -24,65 +24,63 @@ Contributions are very welcome. If you think you need help planning your contrib
One great way you can contribute to the project without writing any code is to help triage issues and pull requests as they come in.
- Ask for more information if you believe the issue does not provide all the details required to solve it.
- Suggest [labels](https://github.com/sveltejs/svelte/labels) that can help categorize issues.
- Flag issues that are stale or that should be closed.
- Ask for test plans and review code.
## Bugs
## Our process
We use [GitHub issues](https://github.com/sveltejs/svelte/issues) for our public bugs. If you would like to report a problem, take a look around and see if someone already opened an issue about it. If you are certain this is a new unreported bug, you can submit a [bug report](#reporting-new-issues).
### RFCs
If you have questions about using Svelte, contact us on Discord at [svelte.dev/chat](https://svelte.dev/chat), and we will do our best to answer your questions.
If you'd like to propose an implementation for a large new feature or change then please [create an RFC](https://github.com/sveltejs/rfcs) to discuss it up front.
If you see anything you'd like to be implemented, create a [feature request issue](https://github.com/sveltejs/svelte/issues/new?template=feature_request.md)
### Roadmap
## Reporting new issues
When deciding where to contribute, you may wish to take a look at [our roadmap](https://svelte.dev/roadmap). The Svelte team generally works on a single major effort at a time. This has a couple benefits for us as maintainers. First, it allows us to focus and make noticeable progress in an area being proactive rather than reactive. Secondly, it allows us to handle related issues and PRs together. By batching issues and PRs together were able to ensure implementations and fixes holistically address the set of problems and use cases encountered by our users.
When [opening a new issue](https://github.com/sveltejs/svelte/issues/new/choose), always make sure to fill out the issue template. **This step is very important!** Not doing so may result in your issue not being managed in a timely fashion. Don't take this personally if this happens, and feel free to open a new issue once you've gathered all the information required by the template.
### Maintainer meetings
- **One issue, one bug:** Please report a single bug per issue.
- **Provide reproduction steps:** List all the steps necessary to reproduce the issue. The person reading your bug report should be able to follow these steps to reproduce your issue with minimal effort. If possible, use the [REPL](https://svelte.dev/repl) to create your reproduction.
The maintainers meet on the final Saturday of each month. While these meetings are not open publicly, we will report back by leaving a comment on each issue discussed. We will generally discuss items aligning with our roadmap, but major PRs needing discussion amongst the maintainers can be added to the agenda for the monthly maintainers meeting. However, we typically are only able to get to a couple of items that are not aligned with our current priority.
## RFCs
### Prioritization
If you'd like to propose an implementation for a large new feature or change then please [create an RFC](https://github.com/sveltejs/rfcs) to discuss it up front.
We do our best to review PRs and RFCs as they are sent, but it is difficult to keep up. We welcome help in reviewing PRs, RFC, and issues. If an item aligns with the current priority on our [roadmap](https://svelte.dev/roadmap), it is more likely to be reviewed quickly. PRs to the most important and active ones repositories get reviewed more quickly while PRs to smaller inactive repos may sit for a bit before we periodically come by and review the pending PRs in a batch.
## Installation
## Bugs
1. Ensure you have [npm](https://www.npmjs.com/get-npm) installed.
1. After cloning the repository, run `npm install` in the root of the repository.
1. To start a development server, run `npm run dev`.
We use [GitHub issues](https://github.com/sveltejs/svelte/issues) for our public bugs. If you would like to report a problem, take a look around and see if someone already opened an issue about it. If you are certain this is a new unreported bug, you can submit a [bug report](#reporting-new-issues).
## Pull requests
If you have questions about using Svelte, contact us on Discord at [svelte.dev/chat](https://svelte.dev/chat), and we will do our best to answer your questions.
### Your first pull request
If you see anything you'd like to be implemented, create a [feature request issue](https://github.com/sveltejs/svelte/issues/new?template=feature_request.md)
So you have decided to contribute code back to upstream by opening a pull request. You've invested a good chunk of time, and we appreciate it. We will do our best to work with you and get the PR looked at.
### Reporting new issues
Working on your first Pull Request? You can learn how from this free video series:
When [opening a new issue](https://github.com/sveltejs/svelte/issues/new/choose), always make sure to fill out the issue template. **This step is very important!** Not doing so may result in your issue not being managed in a timely fashion. Don't take this personally if this happens, and feel free to open a new issue once you've gathered all the information required by the template.
- **One issue, one bug:** Please report a single bug per issue.
- **Provide reproduction steps:** List all the steps necessary to reproduce the issue. The person reading your bug report should be able to follow these steps to reproduce your issue with minimal effort. If possible, use the [REPL](https://svelte.dev/repl) to create your reproduction.
[**How to Contribute to an Open Source Project on GitHub**](https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github)
## Pull requests
### Proposing a change
If you would like to request a new feature or enhancement but are not yet thinking about opening a pull request, you can also file an issue with [feature template](https://github.com/sveltejs/svelte/issues/new?template=feature_request.md).
If you would like to request a new feature or enhancement but are not yet thinking about opening a pull request, you can also file an issue with [feature template](https://github.com/sveltejs/svelte/issues/new?template=feature_request.yml).
If you're only fixing a bug, it's fine to submit a pull request right away but we still recommend that you file an issue detailing what you're fixing. This is helpful in case we don't accept that specific fix but want to keep track of the issue.
If you're only fixing a bug, it's fine to submit a pull request right away, but we still recommend that you file an issue detailing what you're fixing. This is helpful in case we don't accept that specific fix but want to keep track of the issue.
### Sending a pull request
Small pull requests are much easier to review and more likely to get merged.
Small pull requests are much easier to review and more likely to get merged. Make sure the PR does only one thing, otherwise please split it.
### Installation
Please make sure the following is done when submitting a pull request:
1. Ensure you have [npm](https://www.npmjs.com/get-npm) installed.
1. After cloning the repository, run `npm install` in the root of the repository.
1. To start a development server, run `npm run dev`.
1. Fork [the repository](https://github.com/sveltejs/svelte) and create your branch from `master`.
1. Describe your **test plan** in your pull request description. Make sure to test your changes.
1. Make sure your code lints (`npm run lint`).
1. Make sure your tests pass (`npm run test`).
### Creating a branch
All pull requests should be opened against the `master` branch.
Fork [the repository](https://github.com/sveltejs/svelte) and create your branch from `master`. If you've never sent a GitHub pull request before, you can learn how from [this free video series](https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github).
#### Test plan
### Testing
A good test plan has the exact commands you ran and their output, provides screenshots or videos if the pull request changes UI.
@ -110,6 +108,25 @@ Test samples are kept in `/test/xxx/samples` folder.
1. Tests suites like `css`, `js`, `server-side-rendering` asserts that the generated output has to match the content in the `.expected` file. For example, in the `js` test suites, the generated js code is compared against the content in `expected.js`.
1. To update the content of the `.expected` file, run the test with `--update` flag. (`npm run test --update`)
### Style guide
[Eslint](https://eslint.org) will catch most styling issues that may exist in your code. You can check the status of your code styling by simply running `npm run lint`.
#### Code conventions
- `snake_case` for internal variable names and methods.
- `camelCase` for public variable names and methods.
### Sending your pull request
Please make sure the following is done when submitting a pull request:
1. Describe your **test plan** in your pull request description. Make sure to test your changes.
1. Make sure your code lints (`npm run lint`).
1. Make sure your tests pass (`npm run test`).
All pull requests should be opened against the `master` branch. Make sure the PR does only one thing, otherwise please split it.
#### Breaking changes
When adding a new breaking change, follow this template in your pull request:
@ -123,19 +140,10 @@ When adding a new breaking change, follow this template in your pull request:
- **Severity (number of people affected x effort)**:
```
### What happens next?
The core Svelte team will be monitoring for pull requests. Do help us by making your pull request easy to review by following the guidelines above.
## Style guide
[Eslint](https://eslint.org) will catch most styling issues that may exist in your code. You can check the status of your code styling by simply running `npm run lint`.
### Code conventions
- `snake_case` for internal variable names and methods.
- `camelCase` for public variable names and methods.
## License
By contributing to Svelte, you agree that your contributions will be licensed under its [MIT license](https://github.com/sveltejs/svelte/blob/master/LICENSE).
## Questions
Feel free to ask in [#contributing](https://discord.com/channels/457912077277855764/750401468569354431) on [Discord](https://svelte.dev/chat) if you have questions about our process, how to proceed, etc.

@ -1,4 +1,4 @@
Copyright (c) 2016-21 [these people](https://github.com/sveltejs/svelte/graphs/contributors)
Copyright (c) 2016-23 [these people](https://github.com/sveltejs/svelte/graphs/contributors)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

@ -1,17 +1,7 @@
<p>
<a href="https://svelte.dev">
<img alt="Cybernetically enhanced web apps: Svelte" src="https://sveltejs.github.io/assets/banner.png">
</a>
<a href="https://www.npmjs.com/package/svelte">
<img src="https://img.shields.io/npm/v/svelte.svg" alt="npm version">
</a>
<a href="https://github.com/sveltejs/svelte/blob/master/LICENSE">
<img src="https://img.shields.io/npm/l/svelte.svg" alt="license">
</a>
<a href="https://svelte.dev/chat">
<img src="https://img.shields.io/discord/457912077277855764?label=chat&logo=discord" alt="Chat">
</a>
</p>
[![Cybernetically enhanced web apps: Svelte](https://sveltejs.github.io/assets/banner.png)](https://svelte.dev)
[![npm version](https://img.shields.io/npm/v/svelte.svg)](https://www.npmjs.com/package/svelte) [![license](https://img.shields.io/npm/l/svelte.svg)](LICENSE.md) [![Chat](https://img.shields.io/discord/457912077277855764?label=chat&logo=discord)](https://svelte.dev/chat)
## What is Svelte?
@ -30,6 +20,11 @@ Svelte is an MIT-licensed open source project with its ongoing development made
Funds donated via Open Collective will be used for compensating expenses related to Svelte's development such as hosting costs. If sufficient donations are received, funds may also be used to support Svelte's development more directly.
## Roadmap
You may view [our roadmap](https://svelte.dev/roadmap) if you'd like to see what we're currently working on.
## Development
Pull requests are encouraged and always welcome. [Pick an issue](https://github.com/sveltejs/svelte/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc) and help us out!
@ -74,7 +69,7 @@ npm run test -- -g transition
## svelte.dev
The source code for https://svelte.dev, including all the documentation, lives in the [site](site) directory. The site is built with [Sapper](https://sapper.svelte.dev).
The source code for https://svelte.dev lives in the [sites](https://github.com/sveltejs/sites) repository, with all the documentation in the [site/content](site/content) directory. The site is built with [SvelteKit](https://kit.svelte.dev).
### Is svelte.dev down?
@ -82,4 +77,4 @@ Probably not, but it's possible. If you can't seem to access any `.dev` sites, c
## License
[MIT](LICENSE)
[MIT](LICENSE.md)

1591
elements/index.d.ts vendored

File diff suppressed because it is too large Load Diff

@ -0,0 +1,3 @@
{
"types": "./index.d.ts"
}

@ -0,0 +1,23 @@
// This script generates the TypeScript definitions
const { execSync } = require('child_process');
const { readFileSync, writeFileSync } = require('fs');
execSync('tsc -p src/compiler --emitDeclarationOnly && tsc -p src/runtime --emitDeclarationOnly', { stdio: 'inherit' });
// We need to add these types to the .d.ts files here because if we add them before building, the build will fail,
// because the TS->JS transformation doesn't know these exports are types and produces code that fails at runtime.
// We can't use `export type` syntax either because the TS version we're on doesn't have this feature yet.
function modify(path, modifyFn) {
const content = readFileSync(path, 'utf8');
writeFileSync(path, modifyFn(content));
}
modify(
'types/runtime/index.d.ts',
content => content.replace('SvelteComponentTyped', 'SvelteComponentTyped, ComponentType, ComponentConstructorOptions, ComponentProps, ComponentEvents')
);
modify(
'types/compiler/index.d.ts',
content => content + '\nexport { CompileOptions, ModuleFormat, EnableSourcemap, CssHashGetter } from "./interfaces"'
);

8997
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -1,6 +1,6 @@
{
"name": "svelte",
"version": "3.37.0",
"version": "3.56.0",
"description": "Cybernetically enhanced web apps",
"module": "index.mjs",
"main": "index",
@ -9,38 +9,57 @@
"compiler.*",
"register.js",
"index.*",
"ssr.*",
"internal",
"store",
"animate",
"transition",
"easing",
"motion",
"svelte",
"action",
"elements",
"README.md"
],
"exports": {
"./package.json": "./package.json",
".": {
"types": "./types/runtime/index.d.ts",
"browser": {
"import": "./index.mjs",
"require": "./index.js"
},
"node": {
"import": "./ssr.mjs",
"require": "./ssr.js"
},
"import": "./index.mjs",
"require": "./index.js"
},
"./compiler": {
"types": "./types/compiler/index.d.ts",
"import": "./compiler.mjs",
"require": "./compiler.js"
},
"./action": {
"types": "./types/runtime/action/index.d.ts"
},
"./animate": {
"types": "./types/runtime/animate/index.d.ts",
"import": "./animate/index.mjs",
"require": "./animate/index.js"
},
"./easing": {
"types": "./types/runtime/easing/index.d.ts",
"import": "./easing/index.mjs",
"require": "./easing/index.js"
},
"./internal": {
"types": "./types/runtime/internal/index.d.ts",
"import": "./internal/index.mjs",
"require": "./internal/index.js"
},
"./motion": {
"types": "./types/runtime/motion/index.d.ts",
"import": "./motion/index.mjs",
"require": "./motion/index.js"
},
@ -48,12 +67,22 @@
"require": "./register.js"
},
"./store": {
"types": "./types/runtime/store/index.d.ts",
"import": "./store/index.mjs",
"require": "./store/index.js"
},
"./transition": {
"types": "./types/runtime/transition/index.d.ts",
"import": "./transition/index.mjs",
"require": "./transition/index.js"
},
"./elements": {
"types": "./elements/index.d.ts"
},
"./ssr": {
"types": "./types/runtime/index.d.ts",
"import": "./ssr.mjs",
"require": "./ssr.js"
}
},
"engines": {
@ -61,21 +90,17 @@
},
"types": "types/runtime/index.d.ts",
"scripts": {
"test": "mocha",
"test:unit": "mocha --require sucrase/register --recursive src/**/__test__.ts",
"quicktest": "mocha",
"precoverage": "c8 mocha",
"coverage": "c8 report --reporter=text-lcov > coverage.lcov && c8 report --reporter=html",
"codecov": "codecov",
"precodecov": "npm run coverage",
"test": "npm run test:unit && npm run test:integration",
"test:integration": "mocha --exit",
"test:unit": "mocha --config .mocharc.unit.js --exit",
"quicktest": "mocha --exit",
"build": "rollup -c && npm run tsd",
"prepare": "npm run build",
"prepare": "node scripts/skip_in_ci.js npm run build",
"dev": "rollup -cw",
"pretest": "npm run build",
"posttest": "agadoo internal/index.mjs",
"prepublishOnly": "node check_publish_env.js && npm run lint && npm test",
"tsd": "tsc -p src/compiler --emitDeclarationOnly && tsc -p src/runtime --emitDeclarationOnly",
"lint": "eslint \"{src,test}/**/*.{ts,js}\""
"prepublishOnly": "node check_publish_env.js && npm run lint && npm run build && npm test",
"tsd": "node ./generate-type-definitions.js",
"lint": "eslint \"{src,test}/**/*.{ts,js}\" --cache"
},
"repository": {
"type": "git",
@ -92,53 +117,47 @@
"bugs": {
"url": "https://github.com/sveltejs/svelte/issues"
},
"homepage": "https://github.com/sveltejs/svelte#README",
"homepage": "https://svelte.dev",
"devDependencies": {
"@ampproject/remapping": "^0.3.0",
"@jridgewell/sourcemap-codec": "^1.4.14",
"@rollup/plugin-commonjs": "^11.0.0",
"@rollup/plugin-json": "^4.0.1",
"@rollup/plugin-node-resolve": "^6.0.0",
"@rollup/plugin-replace": "^2.3.0",
"@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-node-resolve": "^11.2.1",
"@rollup/plugin-replace": "^5.0.2",
"@rollup/plugin-sucrase": "^3.1.0",
"@rollup/plugin-typescript": "^2.0.1",
"@rollup/plugin-virtual": "^2.0.0",
"@sveltejs/eslint-config": "github:sveltejs/eslint-config#v5.6.0",
"@rollup/plugin-virtual": "^3.0.1",
"@sveltejs/eslint-config": "github:sveltejs/eslint-config#v5.8.0",
"@types/aria-query": "^5.0.1",
"@types/mocha": "^7.0.0",
"@types/node": "^8.10.53",
"@typescript-eslint/eslint-plugin": "^4.9.0",
"@typescript-eslint/parser": "^4.9.0",
"acorn": "^7.4.0",
"agadoo": "^1.1.0",
"c8": "^5.0.1",
"code-red": "^0.1.4",
"codecov": "^3.5.0",
"css-tree": "^1.1.2",
"eslint": "^7.15.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-svelte3": "^2.7.3",
"estree-walker": "^1.0.0",
"is-reference": "^1.1.4",
"@typescript-eslint/eslint-plugin": "^5.29.0",
"@typescript-eslint/parser": "^5.29.0",
"acorn": "^8.8.1",
"agadoo": "^3.0.0",
"aria-query": "^5.1.3",
"axobject-query": "^3.1.1",
"code-red": "^1.0.0",
"css-tree": "^2.3.1",
"eslint": "^8.35.0",
"eslint-plugin-import": "^2.27.0",
"eslint-plugin-svelte3": "^4.0.0",
"estree-walker": "^3.0.3",
"is-reference": "^3.0.1",
"jsdom": "^15.2.1",
"kleur": "^3.0.3",
"kleur": "^4.1.5",
"locate-character": "^2.0.5",
"magic-string": "^0.25.3",
"magic-string": "^0.30.0",
"mocha": "^7.0.0",
"periscopic": "^2.0.1",
"puppeteer": "^2.1.1",
"periscopic": "^3.1.0",
"puppeteer": "^2.0.0",
"rollup": "^1.27.14",
"source-map": "^0.7.3",
"source-map-support": "^0.5.13",
"sourcemap-codec": "^1.4.8",
"tiny-glob": "^0.2.6",
"tslib": "^2.0.3",
"typescript": "^3.7.5"
},
"nyc": {
"include": [
"compiler/svelte.js",
"shared.js"
],
"sourceMap": true,
"instrument": true
"source-map": "^0.7.4",
"source-map-support": "^0.5.21",
"tiny-glob": "^0.2.9",
"tslib": "^2.5.0",
"typescript": "^3.7.5",
"util": "^0.12.5"
}
}

@ -42,6 +42,24 @@ export default [
plugins: [ts_plugin]
},
{
input: `src/runtime/ssr.ts`,
output: [
{
file: `ssr.mjs`,
format: 'esm',
paths: id => id.startsWith('svelte/') && `${id.replace('svelte', '.')}/index.mjs`
},
{
file: `ssr.js`,
format: 'cjs',
paths: id => id.startsWith('svelte/') && `${id.replace('svelte', '.')}/index.js`
}
],
external,
plugins: [ts_plugin]
},
...fs.readdirSync('src/runtime')
.filter(dir => fs.statSync(`src/runtime/${dir}`).isDirectory())
.map(dir => ({
@ -90,8 +108,18 @@ export default [
input: 'src/compiler/index.ts',
plugins: [
replace({
__VERSION__: pkg.version
__VERSION__: pkg.version,
'process.env.NODE_DEBUG': false // appears inside the util package
}),
{
resolveId(id) {
// util is a built-in module in Node.js, but we want a self-contained compiler bundle
// that also works in the browser, so we load its polyfill instead
if (id === 'util') {
return require.resolve('./node_modules/util'); // just 'utils' would resolve this to the built-in module
}
}
},
resolve(),
commonjs({
include: ['node_modules/**']

@ -0,0 +1,91 @@
/** ----------------------------------------------------------------------
This script gets a list of global objects/functions of browser.
This process is simple for now, so it is handled without AST parser.
Please run `node scripts/globals-extractor.mjs` at the project root.
see: https://github.com/microsoft/TypeScript/tree/main/lib
---------------------------------------------------------------------- */
import http from 'https';
import fs from 'fs';
const GLOBAL_TS_PATH = './src/compiler/utils/globals.ts';
// MEMO: add additional objects/functions which existed in `src/compiler/utils/names.ts`
// before this script was introduced but could not be retrieved by this process.
const SPECIALS = ['global', 'globalThis', 'InternalError', 'process', 'undefined'];
const get_url = (name) => `https://raw.githubusercontent.com/microsoft/TypeScript/main/lib/lib.${name}.d.ts`;
const extract_name = (split) => split.match(/^[a-zA-Z0-9_$]+/)[0];
const extract_functions_and_references = (name, data) => {
const functions = [];
const references = [];
data.split('\n').forEach(line => {
const trimmed = line.trim();
const split = trimmed.replace(/[\s+]/, ' ').split(' ');
if (split[0] === 'declare' && split[1] !== 'type') {
functions.push(extract_name(split[2]));
} else if (trimmed.startsWith('/// <reference')) {
const matched = trimmed.match(/ lib="(.+)"/);
const reference = matched && matched[1];
if (reference) references.push(reference);
}
});
return { functions, references };
};
const do_get = (url) => new Promise((resolve, reject) => {
http.get(url, (res) => {
let body = '';
res.setEncoding('utf8');
res.on('data', (chunk) => body += chunk);
res.on('end', () => resolve(body));
}).on('error', (e) => {
console.error(e.message);
reject(e);
});
});
const fetched_names = new Set();
const get_functions = async (name) => {
const res = [];
if (fetched_names.has(name)) return res;
fetched_names.add(name);
const body = await do_get(get_url(name));
const { functions, references } = extract_functions_and_references(name, body);
res.push(...functions);
const chile_functions = await Promise.all(references.map(get_functions));
chile_functions.forEach(i => res.push(...i));
return res;
};
const build_output = (functions) => {
const sorted = Array.from(new Set(functions.sort()));
return `\
/** ----------------------------------------------------------------------
This file is automatically generated by \`scripts/globals-extractor.mjs\`.
Generated At: ${new Date().toISOString()}
---------------------------------------------------------------------- */
export default new Set([
${sorted.map((i) => `\t'${i}'`).join(',\n')}
]);
`;
};
const get_exists_globals = () => {
const regexp = /^\s*["'](.+)["'],?\s*$/;
return fs.readFileSync(GLOBAL_TS_PATH, 'utf8')
.split('\n')
.filter(line => line.match(regexp))
.map(line => line.match(regexp)[1]);
};
(async () => {
const globals = get_exists_globals();
const new_globals = await get_functions('es2021.full');
globals.forEach((g) => new_globals.push(g));
SPECIALS.forEach((g) => new_globals.push(g));
fs.writeFileSync(GLOBAL_TS_PATH, build_output(new_globals));
})();

@ -0,0 +1,7 @@
if (process.env.SKIP_PREPARE) {
console.log('Skipped "prepare" script');
} else {
const { execSync } = require("child_process");
const command = process.argv.slice(2).join(" ");
execSync(command, { stdio: "inherit" });
}

@ -1,9 +0,0 @@
/*
!/Dockerfile
!/package.json
!/package-lock.json
!/__sapper__
/__sapper__/*
!/__sapper__/build
!/static
!/content

@ -1,13 +0,0 @@
NODE_ENV=
PORT=
BASEURL=
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
MAPBOX_ACCESS_TOKEN=
PGHOST=hostname
PGPORT=port
PGUSER=username
PGPASSWORD=password
PGDATABASE=database_name

@ -1,58 +0,0 @@
module.exports = {
root: true,
rules: {
indent: [2, 'tab', { SwitchCase: 1 }],
semi: [2, 'always'],
'keyword-spacing': [2, { before: true, after: true }],
'space-before-blocks': [2, 'always'],
'no-mixed-spaces-and-tabs': [2, 'smart-tabs'],
'no-cond-assign': 0,
'no-unused-vars': 2,
'object-shorthand': [2, 'always'],
'no-const-assign': 2,
'no-class-assign': 2,
'no-this-before-super': 2,
'no-var': 2,
'no-unreachable': 2,
'valid-typeof': 2,
'quote-props': [2, 'as-needed'],
'one-var': [2, 'never'],
'prefer-arrow-callback': 2,
'prefer-const': [2, { destructuring: 'all' }],
'arrow-spacing': 2,
'no-inner-declarations': 0,
'require-atomic-updates': 0
},
env: {
es6: true,
browser: true,
node: true,
mocha: true
},
extends: [
'eslint:recommended',
'plugin:import/errors',
'plugin:import/warnings'
],
plugins: ['svelte3'],
overrides: [
{
files: ['*.svelte'],
processor: 'svelte3/svelte3'
}
],
parserOptions: {
ecmaVersion: 9,
sourceType: 'module'
},
settings: {
'import/core-modules': ['svelte'],
'svelte3/compiler': (() => {
try {
return require('svelte/compiler');
} catch (e) {
return null;
}
})()
}
};

@ -1 +0,0 @@
#!include:.dockerignore

@ -1,11 +0,0 @@
sudo: false
language: node_js
node_js:
- "stable"
env:
global:
- BUILD_TIMEOUT=10000
install:
- npm install
- npm install cypress

@ -1,22 +0,0 @@
# IMPORTANT: Don't use this Dockerfile in your own Sapper projects without also looking at the .dockerignore file.
# Without an appropriate .dockerignore, this Dockerfile will copy a large number of unneeded files into your image.
FROM mhart/alpine-node:12
# install dependencies
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --production
###
# Only copy over the Node pieces we need
# ~> Saves 35MB
###
FROM mhart/alpine-node:slim-12
WORKDIR /app
COPY --from=0 /app .
COPY . .
EXPOSE 3000
CMD ["node", "__sapper__/build"]

@ -1,22 +0,0 @@
HASH := `git rev-parse --short HEAD`
SERVICE := svelte-website
PROJECT := svelte-dev
IMAGE := gcr.io/$(PROJECT)/$(SERVICE):$(HASH)
sapper:
@echo "\n~> updating template & contributors list"
@npm run update
@echo "\n~> building Sapper app"
@npm run build
docker:
@echo "\n~> building docker image"
@gcloud builds submit --project $(PROJECT) -t $(IMAGE)
deploy: sapper docker
@echo "\n~> deploying $(SERVICE) to Cloud Run servers"
@gcloud run deploy $(SERVICE) --project $(PROJECT) --allow-unauthenticated --platform managed --region us-central1 --image $(IMAGE) --memory=512Mi

@ -1,80 +0,0 @@
## Running locally
Set up the site sub-project:
```bash
git clone https://github.com/sveltejs/svelte.git
cd site
npm ci
npm run update
npm run dev
```
and navigate to [localhost:3000](http://localhost:3000).
## Running using the local copy of Svelte
By default, the REPL will fetch the most recent version of Svelte from https://unpkg.com/svelte. When running the site locally, you can also use your local copy of Svelte.
To produce the proper browser-compatible UMD build of the compiler, you will need to run `npm run build` (or `npm run dev`) in the root of this repository with the `PUBLISH` environment variable set to any non-empty string:
```bash
git clone https://github.com/sveltejs/svelte.git
cd svelte
npm ci
PUBLISH=1 npm run build
cd site
npm ci
npm run update
npm run dev
```
Then visit the REPL at [localhost:3000/repl?version=local](http://localhost:3000/repl?version=local). Please note that the local REPL only works with `npm run dev` and not when building the site for production usage.
## REPL GitHub integration
In order for the REPL's GitHub integration to work properly when running locally, you will need to:
- [create a GitHub OAuth app](https://github.com/settings/developers):
- set `Authorization callback URL` to `http://localhost:3000/auth/callback`;
- set `Application name` as you like, and `Homepage URL` as `http://localhost:3000/`;
- create the app and take note of `Client ID` and `Client Secret`
- in this repo, create `site/.env` containing:
```
GITHUB_CLIENT_ID=[your app's Client ID]
GITHUB_CLIENT_SECRET=[your app's Client Secret]
BASEURL=http://localhost:3000
```
## Building the site
To build the website, run `npm run build`. The output can be found in `__sapper__/build`.
## Testing
Tests can be run using `npm run test`.
## Linking `@sveltejs/site-kit` and `@sveltejs/site-repl`
This site depends on `@sveltejs/site-kit`, a collection of styles, components and icons used in common by *.svelte.dev websites, and `@sveltejs/site-repl`.
In order to work on features that depend on those packages, you need to [link](https://docs.npmjs.com/cli/link) their repositories:
- `cd <somewhere>`
- `git clone https://github.com/sveltejs/site-kit`
- `git clone https://github.com/sveltejs/svelte-repl`
- `cd <somewhere>/site-kit`
- `npm link`
- `cd <somewhere>/svelte-repl`
- `npm link`
- `cd <svelte-repo>/site`
- `npm link @sveltejs/site-kit`
- `npm link @sveltejs/svelte-repl`
## Translating the API docs
Anchors are automatically generated using headings in the documentation and by default (for the english language) they are latinised to make sure the URL is always conforming to RFC3986.
If we need to translate the API documentation to a language using unicode chars, we can setup this app to export the correct anchors by setting up `SLUG_PRESERVE_UNICODE` to `true` in `config.js`.

@ -1,17 +0,0 @@
version: "{build}"
shallow_clone: true
init:
- git config --global core.autocrlf false
build: off
environment:
matrix:
# node.js
- nodejs_version: stable
install:
- ps: Install-Product node $env:nodejs_version
- npm install

@ -1,2 +0,0 @@
export const SLUG_PRESERVE_UNICODE = false;
export const SLUG_SEPARATOR = '_';

@ -1,55 +0,0 @@
---
title: Frameworks without the framework: why didn't we think of this sooner?
description: You can't write serious applications in vanilla JavaScript without hitting a complexity wall. But a compiler can do it for you.
author: Rich Harris
authorURL: https://twitter.com/Rich_Harris
---
> Wait, this new framework has a *runtime*? Ugh. Thanks, I'll pass.
> ** front end developers in 2018**
We're shipping too much code to our users. Like a lot of front end developers, I've been in denial about that fact, thinking that it was fine to serve 100kb of JavaScript on page load just use [one less .jpg!](https://twitter.com/miketaylr/status/227056824275333120) and that what *really* mattered was performance once your app was already interactive.
But I was wrong. 100kb of .js isn't equivalent to 100kb of .jpg. It's not just the network time that'll kill your app's startup performance, but the time spent parsing and evaluating your script, during which time the browser becomes completely unresponsive. On mobile, those milliseconds rack up very quickly.
If you're not convinced that this is a problem, follow [Alex Russell](https://twitter.com/slightlylate) on Twitter. Alex [hasn't been making many friends in the framework community lately](https://twitter.com/slightlylate/status/728355959022587905), but he's not wrong. But the proposed alternative to using frameworks like Angular, React and Ember [Polymer](https://www.polymer-project.org/1.0/) hasn't yet gained traction in the front end world, and it's certainly not for a lack of marketing.
Perhaps we need to rethink the whole thing.
## What problem do frameworks *really* solve?
The common view is that frameworks make it easier to manage the complexity of your code: the framework abstracts away all the fussy implementation details with techniques like virtual DOM diffing. But that's not really true. At best, frameworks *move the complexity around*, away from code that you had to write and into code you didn't.
Instead, the reason that ideas like React are so wildly and deservedly successful is that they make it easier to manage the complexity of your *concepts*. Frameworks are primarily a tool for structuring your thoughts, not your code.
Given that, what if the framework *didn't actually run in the browser*? What if, instead, it converted your application into pure vanilla JavaScript, just like Babel converts ES2016+ to ES5? You'd pay no upfront cost of shipping a hefty runtime, and your app would get seriously fast, because there'd be no layers of abstraction between your app and the browser.
## Introducing Svelte
Svelte is a new framework that does exactly that. You write your components using HTML, CSS and JavaScript (plus a few extra bits you can [learn in under 5 minutes](https://v2.svelte.dev/guide)), and during your build process Svelte compiles them into tiny standalone JavaScript modules. By statically analysing the component template, we can make sure that the browser does as little work as possible.
The [Svelte implementation of TodoMVC](https://svelte-todomvc.surge.sh/) weighs 3.6kb zipped. For comparison, React plus ReactDOM *without any app code* weighs about 45kb zipped. It takes about 10x as long for the browser just to evaluate React as it does for Svelte to be up and running with an interactive TodoMVC.
And once your app *is* up and running, according to [js-framework-benchmark](https://github.com/krausest/js-framework-benchmark) **Svelte is fast as heck**. It's faster than React. It's faster than Vue. It's faster than Angular, or Ember, or Ractive, or Preact, or Riot, or Mithril. It's competitive with Inferno, which is probably the fastest UI framework in the world, for now, because [Dominic Gannaway](https://twitter.com/trueadm) is a wizard. (Svelte is slower at removing elements. We're [working on it](https://github.com/sveltejs/svelte/issues/26).)
It's basically as fast as vanilla JS, which makes sense because it *is* vanilla JS  just vanilla JS that you didn't have to write.
## But that's not the important thing
Well, it *is* important performance matters a great deal. What's really exciting about this approach, though, is that we can finally solve some of the thorniest problems in web development.
Consider interoperability. Want to `npm install cool-calendar-widget` and use it in your app? Previously, you could only do that if you were already using (a correct version of) the framework that the widget was designed for if `cool-calendar-widget` was built in React and you're using Angular then, well, hard cheese. But if the widget author used Svelte, apps that use it can be built using whatever technology you like. (On the TODO list: a way to convert Svelte components into web components.)
Or [code splitting](https://twitter.com/samccone/status/797528710085652480). It's a great idea (only load the code the user needs for the initial view, then get the rest later), but there's a problem even if you only initially serve one React component instead of 100, *you still have to serve React itself*. With Svelte, code splitting can be much more effective, because the framework is embedded in the component, and the component is tiny.
Finally, something I've wrestled with a great deal as an open source maintainer: your users always want *their* features prioritised, and underestimate the cost of those features to people who don't need them. A framework author must always balance the long-term health of the project with the desire to meet their users' needs. That's incredibly difficult, because it's hard to anticipate much less articulate the consequences of incremental bloat, and it takes serious soft skills to tell people (who may have been enthusiastically evangelising your tool up to that point) that their feature isn't important enough. But with an approach like Svelte's, many features can be added with absolutely no cost to people who don't use them, because the code that implements those features just doesn't get generated by the compiler if it's unnecessary.
## We're just getting started
Svelte is very new. There's a lot of work still left to do creating build tool integrations, adding a server-side renderer, hot reloading, transitions, more documentation and examples, starter kits, and so on.
But you can already build rich components with it, which is why we've gone straight to a stable 1.0.0 release. [Read the guide](https://v2.svelte.dev/guide), [try it out in the REPL](/repl), and head over to [GitHub](https://github.com/sveltejs/svelte) to help kickstart the next era of front end development.

@ -1,65 +0,0 @@
---
title: The easiest way to get started with Svelte
description: This'll only take a minute.
author: Rich Harris
authorURL: https://twitter.com/Rich_Harris
---
Svelte is a [new kind of framework](/blog/frameworks-without-the-framework). Rather than putting a `<script src='svelte.js'>` tag on the page, or bringing it into your app with `import` or `require`, Svelte is a compiler that works behind the scenes to turn your component files into beautifully optimised JavaScript.
Because of that, getting started with it can be a little bit confusing at first. How, you might reasonably ask, do you make a Svelte app?
## 1. Use the REPL
The [Svelte REPL](repl) is the easiest way to begin. You can choose from a list of examples to get you started, and tweak them until they do what you want.
<aside><p>You'll need to have <a href="https://nodejs.org/">Node.js</a> installed, and know how to use the terminal</p></aside>
At some point, your app will outgrow the REPL. Click the **download** button to save a `svelte-app.zip` file to your computer and uncompress it.
Open a terminal window and set the project up...
```bash
cd /path/to/svelte-app
npm install
```
...then start up a development server:
```bash
npm run dev
```
This will serve your app on [localhost:5000](http://localhost:5000) and rebuild it with [Rollup](https://rollupjs.org) every time you make a change to the files in `svelte-app/src`.
## 2. Use degit
When you download from the REPL, you're getting a customised version of the [sveltejs/template](https://github.com/sveltejs/template) repo. You can skip messing around with zip files by using [degit](https://github.com/Rich-Harris/degit), a project scaffolding tool.
In the terminal, you can instantly create a new project like so:
```bash
npx degit sveltejs/template my-svelte-project
cd my-svelte-project
# to use TypeScript run:
# node scripts/setupTypeScript.js
npm install
npm run dev
```
This will create a new project in the `my-svelte-project` directory, install its dependencies, and start a server on http://localhost:5000.
You can find more information about using TypeScript [here](blog/svelte-and-typescript).
Once you've tinkered a bit and understood how everything fits together, you can fork [sveltejs/template](https://github.com/sveltejs/template) and start doing this instead:
```bash
npx degit your-name/template my-new-project
```
And that's it! Do `npm run build` to create a production-ready version of your app, and check the project template's [README](https://github.com/sveltejs/template/blob/master/README.md) for instructions on how to easily deploy your app to the web with [Vercel](https://vercel.com) or [Surge](http://surge.sh/).
You're not restricted to using Rollup — there are also integrations for [webpack](https://github.com/sveltejs/svelte-loader), [Browserify](https://github.com/tehshrike/sveltify) and others, or you can use the [Svelte CLI](https://github.com/sveltejs/svelte-cli) (Update from 2019: with Svelte 3 the CLI was deprecated and we now use [sirv-cli](https://www.npmjs.com/package/sirv-cli) in our template. Feel free to use whatever tool you like!) or the [API](https://github.com/sveltejs/svelte/tree/v2#api) directly. If you make a project template using one of these tools, please share it with the [Svelte Discord chatroom](chat), or via [@sveltejs](https://twitter.com/sveltejs) on Twitter!

@ -1,78 +0,0 @@
---
title: The zen of Just Writing CSS
description: I would say this is the future, but we're already doing it.
author: Rich Harris
authorURL: https://twitter.com/Rich_Harris
---
It's fashionable to dislike CSS. There are lots of reasons why that's the case, but it boils down to this: CSS is *unpredictable*. If you've never had the experience of tweaking a style rule and accidentally breaking some layout that you thought was completely unrelated — usually when you're trying to ship — then you're either new at this or you're a much better programmer than the rest of us.
So the JavaScript community rolled up its sleeves and got to work. Over the last couple of years, there's been a Cambrian explosion of libraries aimed at making CSS behave, collectively referred to as *CSS-in-JS*.
What you might not realise is that **the biggest problems with CSS can be solved without CSS-in-JS**. Without those problems, writing CSS isn't just tolerable — it's enjoyable. And you don't have to find solutions to the additional problems that CSS-in-JS introduces.
This article isn't in any way intended as criticism of the hard work the CSS-in-JS community has done. It's one of the most active corners of the JS ecosystem, and new ideas are springing up every week. Instead, my purpose is to illustrate why an alternative approach — based on Single File Components with real CSS — is so damn delightful.
## The biggest problem with CSS
Everything in CSS is global. Because of that, styles intended for one bit of markup often end up affecting another. Because of *that*, developers often resort to wild namespacing conventions (not 'rules', since they're very difficult to enforce) that mostly just increase your risk of RSI.
It gets worse when you're working on a team. No-one dares touch styles authored by someone else, because it's often unclear what they're doing, what markup they apply to, and what disasters will unfold if you remove them.
The consequence of all this is the **append-only stylesheet**. There's no way of knowing which code can safely be removed, so it's common to undo some existing style with another, more specific style — even on relatively small projects.
## Single File Components change all that
The idea behind SFCs is simple: you write your components in an HTML file that (optionally) contains a `<style>` and `<script>` attribute describing the component's styles and behaviour. Svelte, Ractive, Vue and Polymer all follow this basic pattern.
<aside>
<p><a href="blog/frameworks-without-the-framework">Read the introductory blog post</a> if you're new to Svelte. Or <a href="https://twitter.com/padolsey/status/899717303234908160">read</a> <a href="https://twitter.com/sveltejs/status/901818357644701696">the</a> <a href="https://twitter.com/sveltejs/status/901818106309476352">testimonials</a>.</p>
</aside>
(For the rest of this article we'll be using Svelte, obviously. But if the idea of using a template language makes you shudder — your fears are misplaced, but that's a topic for another day — then just use Vue which lets you use JSX in your SFCs.)
Several wonderful things happen as a result:
* Your styles are *scoped to the component*. No more leakage, no more unpredictable cascade. And no more sesquipedalian classnames designed to prevent conflicts.
* You don't need to go spelunking through your folder structure to find the rules that are breaking your stuff.
* The compiler (in Svelte's case) can **identify and remove unused styles**. No more append-only stylesheets!
Let's see what that looks like in practice.
<figure>
<video controls poster='https://svelte-technology-assets.surge.sh/just-write-css.jpg'>
<source type='video/mp4' src='https://svelte-technology-assets.surge.sh/just-write-css.mp4'>
</video>
<figcaption>
Is this what they mean by 'use the platform'?
</figcaption>
</figure>
Every code editor already knows about CSS, so there's a good chance that you'll get autocomplete, linting, syntax highlighting and so on — all without additional JS-fatigue-inducing tools.
And because it's real CSS, rather than some camelCased quotes-everywhere impostor, we can take advantage of the 'tweak in devtools, paste back into our source code' workflow, which I personally couldn't live without. Notice that we get CSS sourcemaps out of the box, so you can instantly pinpoint the lines in question. It's hard to overstate the importance of this: when you're in WYSIWYG mode, you're not thinking in terms of your component tree, so having a robust way to figure out *where these damn styles came from* is essential. Doubly so if someone else originally wrote the component. (I promise you, this is the single biggest productivity boost to your CSS workflow. If you're writing styles without sourcemaps, you are almost certainly wasting a lot of time. I know I was.)
Svelte transforms your selectors (using an attribute that's also applied to affected elements, though the exact mechanism is unimportant and subject to change) to achieve the scoping. It warns on and removes any unused rules, then it minifies the result and lets you write it out to a `.css` file. There's also an experimental new option to compile to web components, using shadow DOM to encapsulate the styles, if that's your jam.
This is all possible because your CSS is parsed (with [css-tree](https://github.com/csstree/csstree)) and statically analysed in the context of your markup. Static analysis opens the doors to all kinds of exciting future possibilities — smarter optimisations, a11y hints — that are much harder if your styles are computed dynamically at runtime. We're just getting started.
## But we can add tools to do [x]!
If your reaction to the video was 'fine, but if we use TypeScript and write plugins for each editor then we can get all the autocomplete and syntax highlighting stuff' — in other words, if you believe that in order to achieve parity with CSS it makes sense to build, document, promote and maintain a fleet of ancillary projects — then, well, you and I may never see eye to eye!
## We don't have all the answers — yet
Having said all that, CSS-in-JS does point to answers to some lingering questions:
* How can we install styles from npm?
* How can we reuse constants that are defined in a single place?
* How can we compose declarations?
Personally, I haven't found these issues to outweigh the benefits of the approach outlined above. You may well have a different set of priorities, and they may be reason enough for you to abandon CSS.
But at the end of the day, you have to know CSS anyway. Love it or loathe it, you must at least *learn* it. As custodians of the web, we have a choice: create abstractions that steepen the web dev learning curve yet further, or work together to fix the bad parts of CSS. I know which I choose.

@ -1,84 +0,0 @@
---
title: Sapper: Towards the ideal web app framework
description: Taking the next-plus-one step
author: Rich Harris
authorURL: https://twitter.com/Rich_Harris
---
> Quickstart for the impatient: [the Sapper docs](https://sapper.svelte.dev), and the [starter template](https://github.com/sveltejs/sapper-template)
If you had to list the characteristics of the perfect Node.js web application framework, you'd probably come up with something like this:
1. It should do server-side rendering, for fast initial loads and no caveats around SEO
2. As a corollary, your app's codebase should be universal — write once for server *and* client
3. The client-side app should *hydrate* the server-rendered HTML, attaching event listeners (and so on) to existing elements rather than re-rendering them
4. Navigating to subsequent pages should be instantaneous
5. Offline, and other Progressive Web App characteristics, must be supported out of the box
6. Only the JavaScript and CSS required for the first page should load initially. That means the framework should do automatic code-splitting at the route level, and support dynamic `import(...)` for more granular manual control
7. No compromise on performance
8. First-rate developer experience, with hot module reloading and all the trimmings
9. The resulting codebase should be easy to grok and maintain
10. It should be possible to understand and customise every aspect of the system — no webpack configs locked up in the framework, and as little hidden 'plumbing' as possible
11. Learning the entire framework in under an hour should be easy, and not just for experienced developers
[Next.js](https://github.com/zeit/next.js) is close to this ideal. If you haven't encountered it yet, I strongly recommend going through the tutorials at [learnnextjs.com](https://learnnextjs.com). Next introduced a brilliant idea: all the pages of your app are files in a `your-project/pages` directory, and each of those files is just a React component.
Everything else flows from that breakthrough design decision. Finding the code responsible for a given page is easy, because you can just look at the filesystem rather than playing 'guess the component name'. Project structure bikeshedding is a thing of the past. And the combination of SSR (server-side rendering) and code-splitting — something the React Router team [gave up on](https://reacttraining.com/react-router/web/guides/code-splitting), declaring 'Godspeed those who attempt the server-rendered, code-split apps' — is trivial.
But it's not perfect. As churlish as it might be to list the flaws in something *so, so good*, there are some:
* Next uses something called 'route masking' to create nice URLs (e.g. `/blog/hello-world` instead of `/post?slug=hello-world`). This undermines the guarantee about directory structure corresponding to app structure, and forces you to maintain configuration that translates between the two forms
* All your routes are assumed to be universal 'pages'. But it's very common to need routes that only render on the server, such as a 301 redirect or an [API endpoint](/blog/sapper-towards-the-ideal-web-app-framework.json) that serves the data for your pages, and Next doesn't have a great solution for this. You can add logic to your `server.js` file to handle these cases, but it feels at odds with the declarative approach taken for pages
* To use the client-side router, links can't be standard `<a>` tags. Instead, you have to use framework-specific `<Link>` components, which is impossible in the markdown content for a blog post such as this one, for example
The real problem, though, is that all that goodness comes for a price. The simplest possible Next app — a single 'hello world' page that renders some static text — involves 66kb of gzipped JavaScript. Unzipped, it's 204kb, which is a non-trivial amount of code for a mobile device to parse at a time when performance is a critical factor determining whether or not your users will stick around. And that's the *baseline*.
We can do better!
## The compiler-as-framework paradigm shift
[Svelte introduced a radical idea](blog/frameworks-without-the-framework): what if your UI framework wasn't a framework at all, but a compiler that turned your components into standalone JavaScript modules? Instead of using a library like React or Vue, which knows nothing about your app and must therefore be a one-size-fits-all solution, we can ship highly-optimised vanilla JavaScript. Just the code your app needs, and without the memory and performance overhead of solutions based on a virtual DOM.
The JavaScript world is [moving towards this model](https://tomdale.net/2017/09/compilers-are-the-new-frameworks/). [Stencil](https://stenciljs.com), a Svelte-inspired framework from the Ionic team, compiles to web components. [Glimmer](https://glimmerjs.com) *doesn't* compile to standalone JavaScript (the pros and cons of which deserve a separate blog post), but the team is doing some fascinating research around compiling templates to bytecode. (React is [getting in on the action](https://twitter.com/trueadm/status/944908776896978946), though their current research focuses on optimising your JSX app code, which is arguably more similar to the ahead-of-time optimisations that Angular, Ractive and Vue have been doing for a few years.)
What happens if we use the new model as a starting point?
## Introducing Sapper
<aside><p>The <a href="https://sapper.svelte.dev/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.dev) 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.
The same 'hello world' app that took 204kb with React and Next weighs just 7kb with Sapper. That number is likely to fall further in the future as we explore the space of optimisation possibilities, such as not shipping any JavaScript *at all* for pages that aren't interactive, beyond the tiny Sapper runtime that handles client-side routing.
What about a more 'real world' example? Conveniently, the [RealWorld](https://github.com/gothinkster/realworld) project, which challenges frameworks to develop an implementation of a Medium clone, gives us a way to find out. The [Sapper implementation](https://github.com/sveltejs/realworld) takes 39.6kb (11.8kb zipped) to render an interactive homepage.
<aside><p>Code-splitting isn't free — if the reference implementation used code-splitting, it would be larger still</p></aside>
The entire app costs 132.7kb (39.9kb zipped), which is significantly smaller than the reference React/Redux implementation at 327kb (85.7kb), but even if it was as large it would *feel* faster because of code-splitting. And that's a crucial point. We're told we need to code-split our apps, but if your app uses a traditional framework like React or Vue then there's a hard lower bound on the size of your initial code-split chunk — the framework itself, which is likely to be a significant portion of your total app size. With the Svelte approach, that's no longer the case.
But size is only part of the story. Svelte apps are also extremely performant and memory-efficient, and the framework includes powerful features that you would sacrifice if you chose a 'minimal' or 'simple' UI library.
## Trade-offs
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://v2.svelte.dev/guide#template-syntax)). You get [scoped CSS](blog/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://v2.svelte.dev/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!
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.
And then there's *ecosystem*. The universe around React in particular — the devtools, editor integrations, ancillary libraries, tutorials, StackOverflow answers, hell, even job opportunities — is unrivalled. While it's true that citing 'ecosystem' as the main reason to choose a tool is a sign that you're stuck on a local maximum, apt to be marooned by the rising waters of progress, it's still a major point in favour of incumbents.
## Roadmap
We're not at version 1.0.0 yet, and a few things may change before we get there. Once we do (soon!), there are a lot of exciting possibilities.
I believe the next frontier of web performance is 'whole-app optimisation'. Currently, Svelte's compiler operates at the component level, but a compiler that understood the boundaries *between* those components could generate even more efficient code. The React team's [Prepack research](https://twitter.com/trueadm/status/944908776896978946) is predicated on a similar idea, and the Glimmer team is doing some interesting work in this space. Svelte and Sapper are well positioned to take advantage of these ideas.
Speaking of Glimmer, the idea of compiling components to bytecode is one that we'll probably steal in 2018. A framework like Sapper could conceivably determine which compilation mode to use based on the characteristics of your app. It could even serve JavaScript for the initial route for the fastest possible startup time, then lazily serve a bytecode interpreter for subsequent routes, resulting in the optimal combination of startup size and total app size.
Mostly, though, we want the direction of Sapper to be determined by its users. If you're the kind of developer who enjoys life on the bleeding edge and would like to help shape the future of how we build web apps, please join us on [GitHub](https://github.com/sveltejs/svelte) and [Discord](chat).

@ -1,204 +0,0 @@
---
title: Svelte v2 is out!
description: Here's what you need to know
author: Rich Harris
authorURL: https://twitter.com/Rich_Harris
---
<aside>Our motto is 'move slowly and break things'. No, wait, that came out wrong...</aside>
Almost a year after we first started talking about version 2 on the Svelte issue tracker, it's finally time to make some breaking changes. This blog post will explain what changed, why it changed, and what you need to do to bring your apps up to date.
## tl;dr
Each of these items is described in more depth below. If you get stuck, ask for help in our friendly [Discord chatroom](chat).
- Install Svelte v2 from npm
- Upgrade your templates with [svelte-upgrade](https://github.com/sveltejs/svelte-upgrade)
- Remove calls to `component.observe`, or add the `observe` method from [svelte-extras](https://github.com/sveltejs/svelte-extras)
- Rewrite calls to `component.get('foo')` as `component.get().foo`
- Return `destroy` from your custom event handlers, rather than `teardown`
- Make sure you're not passing numeric string props to components
## New template syntax
The most visible change: we've made some improvements to the template syntax.
A common piece of feedback we heard was 'ewww, Mustache' or 'ewww, Handlebars'. A lot of people who used string-based templating systems in a previous era of web development *really* dislike them. Because Svelte adopted the `{{curlies}}` from those languages, a lot of people assumed that we somehow shared the limitations of those tools, such as weird scoping rules or an inability to use arbitrary JavaScript expressions.
<aside>If you need to show an actual `{` character, it's as easy as `&amp;#123;`</aside>
Beyond that, JSX proved that double curlies are unnecessary. So we've made our templates more... svelte, by adopting single curlies. The result feels much lighter to look at and is more pleasant to type:
```html
<h1>Hello {name}!</h1>
```
There are a few other updates. But you don't need to make them manually — just run [svelte-upgrade](https://github.com/sveltejs/svelte-upgrade) on your codebase:
```bash
npx svelte-upgrade v2 src
```
This assumes any `.html` files in `src` are Svelte components. You can specify whichever directory you like, or target a different directory — for example, you'd do `npx svelte-upgrade v2 routes` to update a [Sapper](https://sapper.svelte.technology) app.
To see the full set of changes, consult the [svelte-upgrade README](https://github.com/sveltejs/svelte-upgrade#svelte-v2-syntax-changes).
## Computed properties
Another thing that people often found confusing about Svelte is the way computed properties work. To recap, if you had a component with this...
```js
export default {
computed: {
d: (a, b, c) => a = b + c
}
};
```
...then Svelte would first look at the function arguments to see which values `d` depended on, and then it would write code that updated `d` whenever those values changed, by injecting them into the function. That's cool, because it allows you to derive complex values from your component's inputs without worrying about when they need to recomputed, but it's also... *weird*. JavaScript doesn't work that way!
In v2, we use [destructuring](http://www.jstips.co/en/javascript/use-destructuring-in-function-parameters/) instead:
```js
export default {
computed: {
d: ({ a, b, c }) => a = b + c
}
};
```
The Svelte compiler can still see which values `d` depends on, but it's no longer injecting values — it just passes the component state object into each computed property.
Again, you don't need to make this change manually — just run svelte-upgrade on your components, as shown above.
## Sorry, IE11. It's not you, it's... well actually, yeah. It's you
Svelte v1 was careful to only emit ES5 code, so that you wouldn't be forced to faff around with transpilers in order to use it. But it's 2018 now, and almost all browsers support modern JavaScript. By ditching the ES5 constraint, we can generate leaner code.
If you need to support IE11 and friends, you will need to use a transpiler like [Babel](http://babeljs.io/repl) or [Bublé](http://buble.surge.sh/).
## New lifecycle hooks
In addition to `oncreate` and `ondestroy`, Svelte v2 adds two more [lifecycle hooks](https://v2.svelte.dev/guide#lifecycle-hooks) for responding to state changes:
```js
export default {
onstate({ changed, current, previous }) {
// this fires before oncreate, and
// whenever state changes
},
onupdate({ changed, current, previous }) {
// this fires after oncreate, and
// whenever the DOM has been updated
// following a state change
}
};
```
You can also listen to those events programmatically:
```js
component.on('state', ({ changed, current, previous }) => {
// ...
});
```
## component.observe
With the new lifecycle hooks, we no longer need the `component.observe(...)` method:
```js
// before
export default {
oncreate() {
this.observe('foo', foo => {
console.log(`foo is now ${foo}`);
});
}
};
// after
export default {
onstate({ changed, current }) {
if (changed.foo) {
console.log(`foo is now ${current.foo}`);
}
}
};
```
This shrinks the amount of code Svelte needs to generate, and gives you more flexibility. For example, it's now very easy to take action when any one of *several* properties have changed, such as redrawing a canvas without debouncing several observers.
However, if you prefer to use `component.observe(...)`, then you can install it from [svelte-extras](https://github.com/sveltejs/svelte-extras):
```js
import { observe } from 'svelte-extras';
export default {
methods: {
observe
}
};
```
## component.get
This method no longer takes an optional `key` argument — instead, it always returns the entire state object:
```js
// before
const foo = this.get('foo');
const bar = this.get('bar');
// after
const { foo, bar } = this.get();
```
This change might seem annoying initially, but it's the right move: among other things, it's likely to play better with type systems as we explore that space more fully in future.
## event_handler.destroy
If your app has [custom event handlers](https://v2.svelte.dev/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).
## No more type coercion
Previously, numeric values passed to components were treated as numbers:
```html
<Counter start='1'/>
```
That causes unexpected behaviour, and has been changed: if you need to pass a literal number, do so as an expression:
```html
<Counter start={1}/>
```
## Compiler changes
In most cases you'll never need to deal with the compiler directly, so this shouldn't require any action on your part. It's worth noting anyway: the compiler API has changed. Instead of an object with a mish-mash of properties, the compiler now returns `js`, `css`, `ast` and `stats`:
```js
const { js, css, ast, stats } = svelte.compile(source, options);
```
`js` and `css` are both `{ code, map }` objects, where `code` is a string and `map` is a sourcemap. The `ast` is an abstract syntax tree of your component, and the `stats` object contains metadata about the component, and information about the compilation.
Before, there was a `svelte.validate` method which checked your component was valid. That's been removed — if you want to check a component without actually compiling it, just pass the `generate: false` option.
## My app is broken! Help!
Hopefully this covers everything, and the update should be easier for you than it was for us. But if you find bugs, or discover things that aren't mentioned here, swing by [Discord chatroom](chat) or raise an issue on the [tracker](https://github.com/sveltejs/svelte/issues).

@ -1,29 +0,0 @@
---
title: Using CSS-in-JS with Svelte
description: You don't need to, but you can
author: Rich Harris
authorURL: https://twitter.com/Rich_Harris
---
CSS is a core part of any web app. By extension, a UI framework that doesn't have a built-in way to add styles to your components is unfinished.
That's why Svelte allows you to add CSS in a component's `<style>` tag. Co-locating your CSS with your markup means we can [solve the biggest problems developers face when writing CSS](/blog/the-zen-of-just-writing-css) without introducing new ones, all while providing a rather nice development experience.
But Svelte's style handling does have some limitations. It's too difficult to share styles between components, or apply app-level optimisations. These are areas we plan to address in future versions, but in the meantime if you need those things you can use any framework-agnostic CSS-in-JS library.
## For example
Here, we're using [Emotion](https://emotion.sh) to generate scoped class names that can be used across multiple components:
<div class="max">
<iframe
title="Aphrodite example"
src="/repl/embed?example=blog-svelte-css-in-js"
scrolling="no"
></iframe>
</div>
It's important to note that most CSS-in-JS libraries have a runtime library, and many don't support statically extracting styles out into a separate <code>.css</code> file at build time (which is essential for the best performance). You should therefore only use CSS-in-JS if it's necessary for your application!
Note that you can mix-and-match — you can still use Svelte's built-in CSS handling alongside a CSS-in-JS library.

@ -1,149 +0,0 @@
---
title: Virtual DOM is pure overhead
description: Let's retire the 'virtual DOM is fast' myth once and for all
author: Rich Harris
authorURL: https://twitter.com/Rich_Harris
---
If you've used JavaScript frameworks in the last few years, you've probably heard the phrase 'the virtual DOM is fast', often said to mean that it's faster than the *real* DOM. It's a surprisingly resilient meme — for example people have asked how Svelte can be fast when it doesn't use a virtual DOM.
It's time to take a closer look.
## What is the virtual DOM?
In many frameworks, you build an app by creating `render()` functions, like this simple [React](https://reactjs.org/) component:
```js
function HelloMessage(props) {
return (
<div className="greeting">
Hello {props.name}
</div>
);
}
```
You can do the same thing without JSX...
```js
function HelloMessage(props) {
return React.createElement(
'div',
{ className: 'greeting' },
'Hello ',
props.name
);
}
```
...but the result is the same — an object representing how the page should now look. That object is the virtual DOM. Every time your app's state updates (for example when the `name` prop changes), you create a new one. The framework's job is to *reconcile* the new one against the old one, to figure out what changes are necessary and apply them to the real DOM.
## How did the meme start?
Misunderstood claims about virtual DOM performance date back to the launch of React. In [Rethinking Best Practices](https://www.youtube.com/watch?v=x7cQ3mrcKaY), a seminal 2013 talk by former React core team member Pete Hunt, we learned the following:
> This is actually extremely fast, primarily because most DOM operations tend to be slow. There's been a lot of performance work on the DOM, but most DOM operations tend to drop frames.
<figure>
<img alt="Pete Hunt at JSConfEU 2013" src="media/rethinking-best-practices.jpg">
<figcaption>Screenshot from <a href="https://www.youtube.com/watch?v=x7cQ3mrcKaY">Rethinking Best Practices</a> at JSConfEU 2013</figcaption>
</figure>
But hang on a minute! The virtual DOM operations are *in addition to* the eventual operations on the real DOM. The only way it could be faster is if we were comparing it to a less efficient framework (there were plenty to go around back in 2013!), or arguing against a straw man — that the alternative is to do something no-one actually does:
```js
onEveryStateChange(() => {
document.body.innerHTML = renderMyApp();
});
```
Pete clarifies soon after...
> React is not magic. Just like you can drop into assembler with C and beat the C compiler, you can drop into raw DOM operations and DOM API calls and beat React if you wanted to. However, using C or Java or JavaScript is an order of magnitude performance improvement because you don't have to worry...about the specifics of the platform. With React you can build applications without even thinking about performance and the default state is fast.
...but that's not the part that stuck.
## So... is the virtual DOM *slow*?
Not exactly. It's more like 'the virtual DOM is usually fast enough', but with certain caveats.
The original promise of React was that you could re-render your entire app on every single state change without worrying about performance. In practice, I don't think that's turned out to be accurate. If it was, there'd be no need for optimisations like `shouldComponentUpdate` (which is a way of telling React when it can safely skip a component).
Even with `shouldComponentUpdate`, updating your entire app's virtual DOM in one go is a lot of work. A while back, the React team introduced something called React Fiber which allows the update to be broken into smaller chunks. This means (among other things) that updates don't block the main thread for long periods of time, though it doesn't reduce the total amount of work or the time an update takes.
## Where does the overhead come from?
Most obviously, [diffing isn't free](https://twitter.com/pcwalton/status/1015694528857047040). You can't apply changes to the real DOM without first comparing the new virtual DOM with the previous snapshot. To take the earlier `HelloMessage` example, suppose the `name` prop changed from 'world' to 'everybody'.
1. Both snapshots contain a single element. In both cases it's a `<div>`, which means we can keep the same DOM node
2. We enumerate all the attributes on the old `<div>` and the new one to see if any need to be changed, added or removed. In both cases we have a single attribute — a `className` with a value of `"greeting"`
3. Descending into the element, we see that the text has changed, so we'll need to update the real DOM
Of these three steps, only the third has value in this case, since — as is the case in the vast majority of updates — the basic structure of the app is unchanged. It would be much more efficient if we could skip straight to step 3:
```js
if (changed.name) {
text.data = name;
}
```
(This is almost exactly the update code that Svelte generates. Unlike traditional UI frameworks, Svelte is a compiler that knows at *build time* how things could change in your app, rather than waiting to do the work at *run time*.)
## It's not just the diffing though
The diffing algorithms used by React and other virtual DOM frameworks are fast. Arguably, the greater overhead is in the components themselves. You wouldn't write code like this...
```js
function StrawManComponent(props) {
const value = expensivelyCalculateValue(props.foo);
return (
<p>the value is {value}</p>
);
}
```
...because you'd be carelessly recalculating `value` on every update, regardless of whether `props.foo` had changed. But it's extremely common to do unnecessary computation and allocation in ways that seem much more benign:
```js
function MoreRealisticComponent(props) {
const [selected, setSelected] = useState(null);
return (
<div>
<p>Selected {selected ? selected.name : 'nothing'}</p>
<ul>
{props.items.map(item =>
<li>
<button onClick={() => setSelected(item)}>
{item.name}
</button>
</li>
)}
</ul>
</div>
);
}
```
Here, we're generating a new array of virtual `<li>` elements — each with their own inline event handler — on every state change, regardless of whether `props.items` has changed. Unless you're unhealthily obsessed with performance, you're not going to optimise that. There's no point. It's plenty fast enough. But you know what would be even faster? *Not doing that.*
<aside><p><a href="https://reactjs.org/docs/hooks-intro.html">React Hooks</a> doubles down on defaulting to doing unnecessary work, with <a href="https://twitter.com/thekitze/status/1078582382201131008">predictable results</a>.</p></aside>
The danger of defaulting to doing unnecessary work, even if that work is trivial, is that your app will eventually succumb to 'death by a thousand cuts' with no clear bottleneck to aim at once it's time to optimise.
Svelte is explicitly designed to prevent you from ending up in that situation.
## Why do frameworks use the virtual DOM then?
It's important to understand that virtual DOM *isn't a feature*. It's a means to an end, the end being declarative, state-driven UI development. Virtual DOM is valuable because it allows you to build apps without thinking about state transitions, with performance that is *generally good enough*. That means less buggy code, and more time spent on creative tasks instead of tedious ones.
But it turns out that we can achieve a similar programming model without using virtual DOM — and that's where Svelte comes in.

@ -1,21 +0,0 @@
---
title: Svelte on The Changelog
description: Listen to the interview here
author: Rich Harris
authorURL: https://twitter.com/Rich_Harris
---
Earlier this month, I had the privilege of appearing on [The Changelog](https://changelog.com/podcast), a podcast about software development. We had a fun (for me) and wide-ranging conversation:
* life as a coder inside a newsroom
* the big compilers-as-frameworks trend
* scalability
* the [Great Divide](https://css-tricks.com/the-great-divide/)
...and, most importantly, Svelte 3.
Unless you hang out in our [Discord server](chat) or follow [@sveltejs](https://twitter.com/sveltejs) on Twitter, you might not know that Svelte 3 is just around the corner, and it's going to be a huge release. We've rethought the developer experience from the ground up, and while it *will* be a nuisance if you need to upgrade a Svelte 2 app (more on that soon) we think you're going to love it.
On the podcast [Adam](https://twitter.com/adamstac), [Jerod](https://twitter.com/jerodsanto) and I talk about some of the changes and why we're making them. You can listen here or on the [podcast page](https://changelog.com/podcast/332).
<audio data-theme="night" style="width: 100%" data-src="https://changelog.com/podcast/332/embed" src="https://cdn.changelog.com/uploads/podcast/332/the-changelog-332.mp3" preload="none" class="changelog-episode" controls></audio><p><a href="https://changelog.com/podcast/332">The Changelog 332: A UI framework without the framework</a> Listen on <a href="https://changelog.com/">Changelog.com</a></p><script async src="//cdn.changelog.com/embed.js"></script>

@ -1,65 +0,0 @@
---
title: Setting up your editor
description: Instructions for configuring linting and syntax highlighting
author: Rich Harris
authorURL: https://twitter.com/Rich_Harris
draft: true
---
*__Coming soon__*
This post will walk you through setting up your editor so that recognises Svelte files:
* eslint-plugin-svelte3
* svelte-vscode
* associating .svelte files with HTML in VSCode, Sublime, etc.
## Atom
To treat `*.svelte` files as HTML, open *__Edit → Config...__* and add the following lines to your `core` section:
```cson
"*":
core:
customFileTypes:
"text.html.basic": [
"svelte"
]
```
## Vim/Neovim
You can use the [coc-svelte extension](https://github.com/coc-extensions/coc-svelte) which utilises the official language-server.
As an alternative you can treat all `*.svelte` files as HTML. Add the following line to your `init.vim`:
```
au! BufNewFile,BufRead *.svelte set ft=html
```
To temporarily turn on HTML syntax highlighting for the current buffer, use:
```
:set ft=html
```
To set the filetype for a single file, use a [modeline](https://vim.fandom.com/wiki/Modeline_magic):
```
<!-- vim: set ft=html :-->
```
## Visual Studio Code
We recommend using the official [Svelte for VS Code extension](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode).
## JetBrains WebStorm
The [Svelte Framework Integration](https://plugins.jetbrains.com/plugin/12375-svelte/) can be used to add support for Svelte to WebStorm, or other Jetbrains IDEs. Consult the [WebStorm plugin installation guide](https://www.jetbrains.com/help/webstorm/managing-plugins.html) on the JetBrains website for more details.
## Sublime Text 3
Open any `.svelte` file.
Go to *__View → Syntax → Open all with current extension as... → HTML__*.

@ -1,107 +0,0 @@
---
title: Svelte for new developers
description: Never used Node.js or the command line? No problem
author: Rich Harris
authorURL: https://twitter.com/Rich_Harris
---
This short guide is designed to help you — someone who has looked at the [tutorial](/tutorial) and wants to start creating Svelte apps, but doesn't have a ton of experience using JavaScript build tooling — get up and running.
If there are things that don't make sense, or that we're glossing over, feel free to [raise an issue](https://github.com/sveltejs/svelte/issues) or [suggest edits to this page](https://github.com/sveltejs/svelte/blob/master/site/content/blog/2019-04-16-svelte-for-new-developers.md) that will help us help more people.
If you get stuck at any point following this guide, the best place to ask for help is in the [chatroom](https://svelte.dev/chat).
## First things first
You'll be using the *command line*, also known as the terminal. On Windows, you can access it by running **Command Prompt** from the Start menu; on a Mac, hit `Cmd` and `Space` together to bring up **Spotlight**, then start typing `Terminal.app`. On most Linux systems, `Ctrl-Alt-T` brings up the command line.
The command line is a way to interact with your computer (or another computer! but that's a topic for another time) with more power and control than the GUI (graphical user interface) that most people use day-to-day.
Once on the command line, you can navigate the filesystem using `ls` (`dir` on Windows) to list the contents of your current directory, and `cd` to change the current directory. For example, if you had a `Development` directory of your projects inside your home directory, you would type
```bash
cd Development
```
to go to it. From there, you could create a new project directory with the `mkdir` command:
```bash
mkdir svelte-projects
cd svelte-projects
```
A full introduction to the command line is out of the scope of this guide, but here are a few more useful commands:
* `cd ..` — navigates to the parent of the current directory
* `cat my-file.txt` — on Mac/Linux (`type my-file.txt` on Windows), lists the contents of `my-file.txt`
* `open .` (or `start .` on Windows) — opens the current directory in Finder or File Explorer
## Installing Node.js
[Node](https://nodejs.org/en/) is a way to run JavaScript on the command line. It's used by many tools, including Svelte. If you don't yet have it installed, the easiest way is to download the latest version straight from the [website](https://nodejs.org/en/).
Once installed, you'll have access to three new commands:
* `node my-file.js` — runs the JavaScript in `my-file.js`
* `npm [subcommand]` — [npm](https://www.npmjs.com/) is a way to install 'packages' that your application depends on, such as the [svelte](https://www.npmjs.com/package/svelte) package
* `npx [subcommand]` — a convenient way to run programs available on npm without permanently installing them
## Installing a text editor
To write code, you need a good editor. The most popular choice is [Visual Studio Code](https://code.visualstudio.com/) or VSCode, and justifiably so — it's well-designed and fully-featured, and has a wealth of extensions ([including one for Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode), which provides syntax highlighting and diagnostic messages when you're writing components).
## Creating a project
We're going to follow the instructions in part two of [The easiest way to get started with Svelte](/blog/the-easiest-way-to-get-started).
First, we'll use npx to run [degit](https://github.com/Rich-Harris/degit), a program for cloning project templates from [GitHub](https://github.com) and other code storage websites. You don't have to use a project template, but it means you have to do a lot less setup work. You will need to have [Git](https://git-scm.com/) installed in order to use degit. (Eventually you'll probably have to learn [Git](https://git-scm.com/) itself, which most programmers use to manage their projects.)
On the command line, navigate to where you want to create a new project, then type the following lines (you can paste the whole lot, but you'll develop better muscle memory if you get into the habit of writing each line out one at a time then running it):
```bash
npx degit sveltejs/template my-svelte-project
cd my-svelte-project
npm install
```
This creates a new directory, `my-svelte-project`, adds files from the [sveltejs/template](https://github.com/sveltejs/template) code repository, and installs a number of packages from npm. Open the directory in your text editor and take a look around. The app's 'source code' lives in the `src` directory, while the files your app can load are in `public`.
In the `package.json` file, there is a section called `"scripts"`. These scripts define shortcuts for working with your application — `dev`, `build` and `start`. To launch your app in development mode, type the following:
```bash
npm run dev
```
Running the `dev` script starts a program called [Rollup](https://rollupjs.org/guide/en/). Rollup's job is to take your application's source files (so far, just `src/main.js` and `src/App.svelte`), pass them to other programs (including Svelte, in our case) and convert them into the code that will actually run when you open the application in a browser.
Speaking of which, open a browser and navigate to http://localhost:5000. This is your application running on a local *web server* (hence 'localhost') on port 5000.
Try changing `src/App.svelte` and saving it. The application will reload with your changes.
## Building your app
In the last step, we were running the app in 'development mode'. In dev mode, Svelte adds extra code that helps with debugging, and Rollup skips the final step where your app's JavaScript is compressed using [Terser](https://terser.org/).
When you share your app with the world, you want to build it in 'production mode', so that it's as small and efficient as possible for end users. To do that, use the `build` command:
```bash
npm run build
```
Your `public` directory now contains a compressed `bundle.js` file containing your app's JavaScript. You can run it like so:
```bash
npm run start
```
This will run the app on http://localhost:5000.
## Next steps
To share your app with the world you'll need to *deploy* it. There are many ways to do so — some are listed in the `README.md` file inside your project.

@ -1,164 +0,0 @@
---
title: Write less code
description: The most important metric you're not paying attention to
author: Rich Harris
authorURL: https://twitter.com/Rich_Harris
---
All code is buggy. It stands to reason, therefore, that the more code you have to write the buggier your apps will be.
Writing more code also takes more time, leaving less time for other things like optimisation, nice-to-have features, or being outdoors instead of hunched over a laptop.
In fact it's widely acknowledged that [project development time](https://blog.codinghorror.com/diseconomies-of-scale-and-lines-of-code/) and [bug count](https://www.mayerdan.com/ruby/2012/11/11/bugs-per-line-of-code-ratio) grow *quadratically*, not linearly, with the size of a codebase. That tracks with our intuitions: a ten-line pull request will get a level of scrutiny rarely applied to a 100-line one. And once a given module becomes too big to fit on a single screen, the cognitive effort required to understand it increases significantly. We compensate by refactoring and adding comments — activities that almost always result in *more* code. It's a vicious cycle.
Yet while we obsess — rightly! — over performance numbers, bundle size and anything else we can measure, we rarely pay attention to the amount of code we're writing.
## Readability is important
I'm certainly not claiming that we should use clever tricks to scrunch our code into the most compact form possible at the expense of readability. Nor am I claiming that reducing *lines* of code is necessarily a worthwhile goal, since it encourages turning readable code like this...
```js
for (let i = 0; i <= 100; i += 1) {
if (i % 2 === 0) {
console.log(`${i} is even`);
}
}
```
...into something much harder to parse:
```js
for (let i = 0; i <= 100; i += 1) if (i % 2 === 0) console.log(`${i} is even`);
```
Instead, I'm claiming that we should favour languages and patterns that allow us to naturally write less code.
## Yes, I'm talking about Svelte
Reducing the amount of code you have to write is an explicit goal of Svelte. To illustrate, let's look at a very simple component implemented in React, Vue and Svelte. First, the Svelte version:
<div class="max">
<iframe
title="Simple component example"
src="/repl/embed?example=blog-write-less-code"
scrolling="no"
></iframe>
</div>
How would we build this in React? It would probably look something like this:
```js
import React, { useState } from 'react';
export default () => {
const [a, setA] = useState(1);
const [b, setB] = useState(2);
function handleChangeA(event) {
setA(+event.target.value);
}
function handleChangeB(event) {
setB(+event.target.value);
}
return (
<div>
<input type="number" value={a} onChange={handleChangeA}/>
<input type="number" value={b} onChange={handleChangeB}/>
<p>{a} + {b} = {a + b}</p>
</div>
);
};
```
Here's an equivalent component in Vue:
```html
<template>
<div>
<input type="number" v-model.number="a">
<input type="number" v-model.number="b">
<p>{{a}} + {{b}} = {{a + b}}</p>
</div>
</template>
<script>
export default {
data: function() {
return {
a: 1,
b: 2
};
}
};
</script>
```
<aside>
<p>I'm counting by copying the source code to the clipboard and running `pbpaste | wc -c` in my terminal</p>
</aside>
In other words, it takes 442 characters in React, and 263 characters in Vue, to achieve something that takes 145 characters in Svelte. The React version is literally three times larger!
It's unusual for the difference to be *quite* so obvious — in my experience, a React component is typically around 40% larger than its Svelte equivalent. Let's look at the features of Svelte's design that enable you to express ideas more concisely:
### Top-level elements
In Svelte, a component can have as many top-level elements as you like. In React and Vue, a component must have a single top-level element — in React's case, trying to return two top-level elements from a component function would result in syntactically invalid code. (You can use a fragment — `<>` instead of a `<div>`, but it's the same basic idea, and still results in an extra level of indentation).
In Vue, your markup must be wrapped in a `<template>` element, which I'd argue is redundant.
### Bindings
In React, we have to respond to input events ourselves:
```js
function handleChangeA(event) {
setA(+event.target.value);
}
```
This isn't just boring plumbing that takes up extra space on the screen, it's also extra surface area for bugs. Conceptually, the value of the input is bound to the value of `a` and vice versa, but that relationship isn't cleanly expressed — instead we have two tightly-coupled but physically separate chunks of code (the event handler and the `value={a}` prop). Not only that, but we have to remember to coerce the string value with the `+` operator, otherwise `2 + 2` will equal `22` instead of `4`.
Like Svelte, Vue does have a way of expressing the binding — the `v-model` attribute, though again we have to be careful to use `v-model.number` even though it's a numeric input.
### State
In Svelte, you update local component state with an assignment operator:
```js
let count = 0;
function increment() {
count += 1;
}
```
In React, we use the `useState` hook:
```js
const [count, setCount] = useState(0);
function increment() {
setCount(count + 1);
}
```
This is much *noisier* — it expresses the exact same concept but with over 60% more characters. As you're reading the code, you have to do that much more work to understand the author's intent.
In Vue, meanwhile, we have a default export with a `data` function that returns an object literal with properties corresponding to our local state. Things like helper functions and child components can't simply be imported and used in the template, but must instead be 'registered' by attaching them to the correct part of the default export.
## Death to boilerplate
These are just some of the ways that Svelte helps you build user interfaces with a minimum of fuss. There are plenty of others — for example, [reactive declarations](tutorial/reactive-declarations) essentially do the work of React's `useMemo`, `useCallback` and `useEffect` without the boilerplate (or indeed the garbage collection overhead of creating inline functions and arrays on each state change).
How? By choosing a different set of constraints. Because [Svelte is a compiler](blog/frameworks-without-the-framework), we're not bound to the peculiarities of JavaScript: we can *design* a component authoring experience, rather than having to fit it around the semantics of the language. Paradoxically, this results in *more* idiomatic code — for example using variables naturally rather than via proxies or hooks — while delivering significantly more performant apps.

@ -1,97 +0,0 @@
---
title: Svelte 3: Rethinking reactivity
description: It's finally here
author: Rich Harris
authorURL: https://twitter.com/Rich_Harris
---
After several months of being just days away, we are over the moon to announce the stable release of Svelte 3. This is a huge release representing hundreds of hours of work by many people in the Svelte community, including invaluable feedback from beta testers who have helped shape the design every step of the way.
We think you're going to love it.
## What is Svelte?
Svelte is a component framework — like React or Vue — but with an important difference. Traditional frameworks allow you to write *declarative* state-driven code, but there's a penalty: the browser must do extra work to convert those declarative structures into DOM operations, using techniques like [virtual DOM diffing](blog/virtual-dom-is-pure-overhead) that eat into your frame budget and tax the garbage collector.
Instead, Svelte runs at *build time*, converting your components into highly efficient *imperative* code that surgically updates the DOM. As a result, you're able to write ambitious applications with excellent performance characteristics.
The first version of Svelte was all about [testing a hypothesis](blog/frameworks-without-the-framework) — that a purpose-built compiler could generate rock-solid code that delivered a great user experience. The second was a small upgrade that tidied things up a bit.
Version 3 is a significant overhaul. Our focus for the last five or six months has been on delivering an outstanding *developer* experience. It's now possible to write components with [significantly less boilerplate](blog/write-less-code) than you'll find elsewhere. Try the brand new [tutorial](tutorial) and see what we mean — if you're familiar with other frameworks we think you'll be pleasantly surprised.
To make that possible we first needed to rethink the concept at the heart of modern UI frameworks: reactivity.
<div class="max">
<figure style="max-width: 960px; margin: 0 auto">
<div style="height: 0; padding: 0 0 57.1% 0; position: relative; margin: 0 auto;">
<iframe style="position: absolute; width: 100%; height: 100%; left: 0; top: 0; margin: 0;" src="https://www.youtube-nocookie.com/embed/AdNJ3fydeao" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
<figcaption>'Rethinking Reactivity' from <a href="https://www.israel.yglfconf.com/">You Gotta Love Frontend Code Camp</a></figcaption>
</figure>
</div>
## Moving reactivity into the language
In old Svelte, you would tell the computer that some state had changed by calling the `this.set` method:
```js
const { count } = this.get();
this.set({
count: count + 1
});
```
That would cause the component to *react*. Speaking of which, `this.set` is almost identical to the `this.setState` method used in classical (pre-hooks) React:
```js
const { count } = this.state;
this.setState({
count: count + 1
});
```
There are some important technical differences (as I explain in the video above, React is not reactive) but conceptually it's the same thing.
<aside>
<p>In fact, Svelte 3 is basically <a href="https://twitter.com/threepointone/status/1057179801109311488">Sunil's fault</a>.</p>
</aside>
That all changed with the advent of [hooks](https://reactjs.org/docs/hooks-intro.html), which handle state in a very different fashion. Many frameworks started experimenting with their own implementations of hooks, but we quickly concluded it wasn't a direction we wanted to go in. Hooks have some intriguing properties, but they also involve some unnatural code and create unnecessary work for the garbage collector. For a framework that's used in [embedded devices](https://mobile.twitter.com/sveltejs/status/1088500539640418304) as well as animation-heavy interactives, that's no good.
So we took a step back and asked ourselves what kind of API would work for us... and realised that the best API is no API at all. We can just *use the language*. Updating some `count` value — and all the things that depend on it — should be as simple as this:
```js
count += 1;
```
Since we're a compiler, we can do that by instrumenting assignments behind the scenes:
```js
count += 1; $$invalidate('count', count);
```
Importantly, we can do all this without the overhead and complexity of using proxies or accessors. It's just a variable.
## New look
Your components aren't the only thing that's getting a facelift. Svelte itself has a completely new look and feel, thanks to the amazing design work of [Achim Vedam](https://vedam.de/) who created our new logo and website, which has moved from [svelte.technology](https://svelte.technology) to [svelte.dev](https://svelte.dev).
We've also changed our tagline, from 'The magical disappearing UI framework' to 'Cybernetically enhanced web apps'. Svelte has many aspects — outstanding performance, small bundles, accessibility, built-in style encapsulation, declarative transitions, ease of use, the fact that it's a compiler, etc — that focusing on any one of them feels like an injustice to the others. 'Cybernetically enhanced' is designed to instead evoke Svelte's overarching philosophy that our tools should work as intelligent extensions of ourselves — hopefully with a retro, William Gibson-esque twist.
## Upgrading from version 2
If you're an existing Svelte 2 user, I'm afraid there is going to be some manual upgrading involved. In the coming days we'll release a migration guide and an updated version of [svelte-upgrade](https://github.com/sveltejs/svelte-upgrade) which will do the best it can to automate the process, but this *is* a significant change and not everything can be handled automatically.
We don't take this lightly: hopefully once you've experienced Svelte 3 you'll understand why we felt it was necessary to break with the past.
## Still to come
As grueling as this release has been, we're nowhere near finished. We have a ton of ideas for generating smarter, more compact code, and a long feature wish-list. [Sapper](https://sapper.svelte.dev), our Next.js-style app framework, is still in the middle of being updated to use Svelte 3. The [Svelte Native](https://svelte-native.technology/) community project, which allows you to write Android and iOS apps in Svelte, is making solid progress but deserves more complete support from core. We don't yet have the bounty of editor extensions, syntax highlighters, component kits, devtools and so on that other frameworks have, and we should fix that. We *really* want to add first-class TypeScript support.
But in the meantime we think Svelte 3 is the best way to build web apps yet. Take an hour to go through the [tutorial](tutorial) and we hope to convince you of the same. Either way, we'd love to see you in our [Discord chatroom](chat) and on [GitHub](https://github.com/sveltejs/svelte) — everyone is welcome, especially you.

@ -1,141 +0,0 @@
---
title: Svelte <3 TypeScript
description: Typernetically enhanced web apps
author: Orta Therox
authorURL: https://twitter.com/orta
---
It's been by far the most requested feature for a while, and it's finally here: Svelte officially supports TypeScript.
We think it'll give you a much nicer development experience — one that also scales beautifully to larger Svelte code bases — regardless of whether you use TypeScript or JavaScript.
<figure>
<img alt="Screenshot of TypeScript in Svelte" src="media/svelte-ts.png">
<figcaption>Image of TypeScript + Svelte in VS Code (theme is <a href="https://marketplace.visualstudio.com/items?itemName=karyfoundation.theme-karyfoundation-themes">Kary Pro</a>.)</figcaption>
</figure>
## Try it now
You can start a new Svelte TypeScript project using the [normal template](https://github.com/sveltejs/template) and by running `node scripts/setupTypeScript.js` before you do anything else:
```bash
npx degit sveltejs/template svelte-typescript-app
cd svelte-typescript-app
node scripts/setupTypeScript.js
```
If you're a VS Code user, make sure you're using the (new) [official extension](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode), which replaces the popular extension by James Birtles.
Later in this blog post, we'll detail the individual steps involved in using TypeScript in an existing Svelte project.
## What does it mean to support TypeScript in Svelte?
TypeScript support in Svelte has been possible for a long time, but you had to mix a lot of disparate tools together and each project ran independently. Today, nearly all of these tools live under the Svelte organization and are maintained by a set of people who take responsibility over the whole pipeline and have common goals.
A week before COVID was declared a pandemic, [I pitched a consolidation](https://github.com/sveltejs/svelte/issues/4518) of the best Svelte tools and ideas from similar dev-ecosystems and provided a set of steps to get first class TypeScript support. Since then, many people have pitched in and written the code to get us there.
When we say that Svelte now supports TypeScript, we mean a few different things:
* You can use TypeScript inside your `<script>` blocks — just add the `lang="ts"` attribute
* Components with TypeScript can be type-checked with the `svelte-check` command
* You get autocompletion hints and type-checking as you're writing components, even in expressions inside markup
* TypeScript files understand the Svelte component API — no more red squiggles when you import a `.svelte` file into a `.ts` module
#### How does it work?
To understand the two main parts of TypeScript support, we'll compare it to the technique TypeScript uses to provide dev tools. There is a compiler `tsc` which you run on the command-line to convert `*.ts` to `*.js`, then there is a `TSServer` which is a node API that responds to requests from text editors. The `TSServer` is what provides all the JavaScript and TypeScript realtime introspection for editors while coding, and it has most of the compiler's code inside it.
For Svelte, we have the Svelte compiler, and now we have the [`svelte-language-server`](https://github.com/sveltejs/language-tools/tree/master/packages/language-server#svelte-language-server) which responds to text editor calls via the [Language Server Protocol standard](https://microsoft.github.io//language-server-protocol/overviews/lsp/overview/). First class TypeScript support means that _both_ of these two systems do a good job of handling TypeScript code.
The Svelte compiler support for TypeScript is handled by [Christian Kaisermann](https://github.com/kaisermann)'s [`svelte-preprocess`](https://github.com/sveltejs/svelte-preprocess#svelte-preprocess) which is now an official Svelte project.
For the editor level, we took inspiration from [Pine's](https://github.com/octref) work in the [Vue](https://vuejs.org) ecosystem via [Vetur](https://github.com/vuejs/vetur). Vetur provides an [LSP](https://github.com/vuejs/vetur/blob/master/server), a VS Code extension and a [CLI](https://github.com/vuejs/vetur/blob/master/vti). Svelte now also has an [LSP](https://github.com/sveltejs/language-tools/blob/master/packages/language-server), a [VS Code extension](https://github.com/sveltejs/language-tools/blob/master/packages/svelte-vscode) and a [CLI](https://github.com/sveltejs/language-tools/blob/master/packages/svelte-check).
#### `*.svelte` Introspection
For the official Svelte VS Code extension, we built off the foundations which [James Birtles](https://github.com/UnwrittenFun) has created in [`UnwrittenFun/svelte-vscode`](https://github.com/UnwrittenFun/svelte-vscode) and [`UnwrittenFun/svelte-language-server`](https://github.com/UnwrittenFun/svelte-language-server/).
[Simon Holthausen](https://github.com/dummdidumm) and [Lyu, Wei-Da](https://github.com/jasonlyu123) have done great work improving the JavaScript and TypeScript introspection, including integrating [@halfnelson](https://github.com/halfnelson)'s [svelte2tsx](https://github.com/sveltejs/language-tools/tree/master/packages/svelte2tsx#svelte2tsx) which powers understanding the props on components in your codebase.
## Adding TypeScript to an existing project
Before getting started, add the dependencies:
```bash
npm install --save-dev @tsconfig/svelte typescript svelte-preprocess svelte-check
```
##### 1. Compiling TypeScript
You first need to set up [`svelte-preprocess`](https://github.com/sveltejs/svelte-preprocess#svelte-preprocess), which passes the contents of your `<script lang="ts">` blocks through the TypeScript compiler.
In a Rollup project, that would look like this — note that we also need to install `@rollup/plugin-typescript` so that Rollup can handle `.ts` files:
```diff
+ import autoPreprocess from 'svelte-preprocess';
+ import typescript from '@rollup/plugin-typescript';
export default {
...,
plugins: [
svelte({
+ preprocess: autoPreprocess()
}),
+ typescript({ sourceMap: !production })
]
}
```
[Full instructions for other environments here](https://github.com/sveltejs/svelte-preprocess#usage).
To configure TypeScript, you will need to create a `tsconfig.json` in the root of your project:
```json
{
"extends": "@tsconfig/svelte/tsconfig.json",
"include": ["src/**/*", "src/node_modules"],
"exclude": ["node_modules/*", "__sapper__/*", "public/*"],
}
```
Your `include`/`exclude` may differ per project — these are defaults that should work across most Svelte projects.
##### 2. Editor Support
Any editor [using an LSP](https://langserver.org/#implementations-client) can be supported. The [VS Code](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode) extension has been our primary focus, but there is work in progress [on Atom](https://github.com/sveltejs/language-tools/pull/160), and Vim via [coc-svelte](https://github.com/coc-extensions/coc-svelte) has been updated with the latest LSP.
These editor extensions will improve your coding experience even if you only use JavaScript. The editor won't offer errors, but it will offer inference and refactoring tools. You can [add `// @ts-check`](https://www.staging-typescript.org/docs/handbook/intro-to-js-ts.html) to the top of a `<script>` tag using JavaScript to get better error messages with no infra changes.
To switch a `<script>` to use TypeScript, use `<script lang="ts">` and that should be it. Hopefully you won't be seeing an ocean of red squiggles.
##### 3. CI Checks
Having red squiggles is great, well, kinda. On the long run though, you want to be able to verify that there are no errors in your code. To verify your project is error free, you can use the CLI tool [`svelte-check`](https://www.npmjs.com/package/svelte-check). It acts like an editor asking for errors against all of your `.svelte` files.
You can add the dependency to your project and then add it to CI.
```bash
npx svelte-check
Loading svelte-check in workspace: /Users/ortatherox/dev/svelte/example-app
Getting Svelte diagnostics...
====================================
/Users/ortatherox/dev/svelte/example-app/src/App.svelte:3:2
Error: Type '123' is not assignable to type 'string'. (ts)
====================================
svelte-check found 1 error
error Command failed with exit code 1.
```
## What about TypeScript in Sapper projects?
TypeScript support was added to Sapper in 0.28, so if you're using an older version be sure to [upgrade](https://sapper.svelte.dev/migrating#0_27_to_0_28).
## How can I contribute?
We're so glad you asked. The work is happening in the [sveltejs/language-tools](https://github.com/sveltejs/language-tools) repo and in the [#language-tools](https://discord.gg/enV6v8K) channel in the Svelte Discord. If you'd like to report issues, submit fixes, or help out with extensions for new editors and so on, that's where you can find us. See you there!

@ -1,85 +0,0 @@
---
title: What's new in Svelte: October 2020
description: New object methods, in-depth learning resources and tons of integration examples!
author: Daniel Sandoval
authorURL: https://desandoval.net
---
Welcome to the first edition of our "What's new in Svelte" series! We'll try to make this a monthly blog post in which you'll find out about new features, bug fixes, and a showcase of Svelte projects from around the community.
## New features
1. `use:obj.method` allows functions defined within objects to be used within actions ([Example](https://svelte.dev/repl/c305722adb4a4545b27b198ea8ff9bde?version=3.27.0), **3.26.0**, warning removed in **3.27.0**)
2. `_` is now supported as a "numerical separator", similar to a `.` or `,` ([Example](https://svelte.dev/repl/844c39e91d1248649fe54af839fab570?version=3.26.0), **3.26.0**)
3. `import.meta` now works in template expressions ([Example](https://svelte.dev/repl/9630de41957a4c80a4fce264360a6bc7?version=3.26.0), **3.26.0**)
4. CSS Selectors with `~` and `+` combinators are now supported ([Example](https://svelte.dev/repl/91ad9257d2d1430185a504a18cc60172?version=3.29.0), **3.27.0**, with a compiler fix in **3.29.0**)
5. The `{#key}` block is now available to key arbitrary content on an expression. Whever the expression changes, the contents inside the `{#key}` block will be destroyed and recreated. For an in-depth explanation and to find out how it's implemented, check out the [new blog post](https://lihautan.com/contributing-to-svelte-implement-key-block/) of Svelte Team member Tan Li Hau. ([More info](https://github.com/sveltejs/svelte/issues/1469), **3.29.0**)
6. Slots can now be forwarded through child components! This used to only be possible by adding extra wrapper `<div>`s ([More info](https://github.com/sveltejs/svelte/issues/2079), **3.29.0**)
7. When using TypeScript, you can now type the `createEventDispatcher` method:
```html
<script lang="ts">
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher<{
/**
* you can also add docs
*/
checked: boolean; // Will translate to `CustomEvent<boolean>`
hello: string;
}>();
// ...
</script>
```
This will make sure that you can invoke dispatch only with the specified event names and its types. The Svelte for VS Code extension was also updated to deal with this new feature. It will provide strong typings for these events as well as autocompletion and hover information.
**New from Sapper!**
Sapper 0.28.9 just came out. The highlights from it include much better support for CSP nonces, asset preload support for exported pages, and error details are now available in the `$page` store on error pages.
In addition, Sapper's CSS handling has been rewritten over the course of recent releases in order to fix existing CSS handling bugs, refactor the CSS handling to occur entirely within a Rollup plugin, and remove the need internally to register CSS in the routing system. Congrats and thank you to the folks working on Sapper for all their solid work!
## Impactful bug fixes
- CSS compilation will no longer remove rules for the `open` attribute on `<details>` elements ([Example](https://svelte.dev/repl/ab4c0c177d1f4fab92f46eb8539cea9a?version=3.26.0), **3.26.0**)
- `prettier-plugin-svelte` will do a better job now at dealing with whitespaces, especially around inline elements. It will also preserve formatting inside `<pre>` tags and will no longer format languages which are not supported by Prettier, like SASS, Pug or Stylus.
## Coming up
- [Svelte Summit](https://sveltesummit.com/), Svelte's second global online conference, is taking place on October 18! Sign up for free to get reminders and talk updates!
For all the features and bugfixes see the CHANGELOG for [Svelte](https://github.com/sveltejs/svelte/blob/master/CHANGELOG.md) and [Sapper](https://github.com/sveltejs/sapper/blob/master/CHANGELOG.md).
---
## Svelte Showcase
- [This CustomMenu example](https://svelte.dev/repl/3a33725c3adb4f57b46b597f9dade0c1?version=3.25.0) demos how to replace the OS right-click menu
- [Github Tetris](https://svelte.dev/repl/cc1eaa7c66964fedb5e70e3ecbbaa0e1?version=3.25.1) lets you play a Tetris-like game in a git commit history
- [Who are my representatives?](https://whoaremyrepresentatives.us/) is a website built with Svelte to help US residents get more info on their congressional representatives
- [Pick Palette](https://github.com/bluwy/pick-palette) is a color palette manager made with Svelte!
#### In-depth learning:
- [Svelte 3 Up and Running](https://www.amazon.com/dp/B08D6T6BKS/ref=cm_sw_r_tw_dp_x_OQMtFb3GPQCB2) is a new book about building production-ready static web apps with Svelte 3
- [Sapper Tutorial (Crash Course)](https://www.youtube.com/playlist?list=PL4cUxeGkcC9gdr4Qhx83gBBcID-KMe-PQ) walks through the ins-and-outs of Sapper, the Svelte-powered application framework
- [Svelte Society Day France](https://france.sveltesociety.dev/) happened September 27th featuring a wide variety of topics all in French! You can find the full recording [here](https://www.youtube.com/watch?v=aS1TQ155JK4).
#### Plug-and-play components:
- [svelte-zoom](https://github.com/vaheqelyan/svelte-zoom) brings "nearly native" pan-and-zoom to images on desktop and mobile
- [svelte-materialify](https://github.com/TheComputerM/svelte-materialify) is a Material component library for Svelte with over 50 components
- [svelte-undoable](https://github.com/macfja/svelte-undoable) makes it easy to introduce undo and redo functionality using `bind:`
- [This Tilt component](https://svelte.dev/repl/7b23ad9d2693424482cd411b0378b55b?version=3.24.1) implements a common UX pattern where the hovered element tilts to follow the mouse
#### Lots of examples of how use JS tech came out this month:
- [Sapper with PostCSS and Tailwind](https://codechips.me/sapper-with-postcss-and-tailwind/)
- [PrismJS (Code block syntax highlighting)](https://github.com/phptuts/Svelte-PrismJS)
- [Filepond (Drag-and-drop file upload)](https://github.com/pqina/svelte-filepond)
- [Ionic (UI Components)](https://github.com/Tommertom/svelte-ionic-app)
- [Pell (WYSIWYG Editor)](https://github.com/Demonicious/svelte-pell/)
- [Leaflet (Mapping)](https://github.com/anoram/leaflet-svelte)
**Reminder**: There's a [Svelte integrations repo](https://github.com/sveltejs/integrations) that demonstrates ways to incorporate Svelte into your stack (and vice versa). If you've got questions on how to use a particular piece of tech with Svelte, you may find your answer there... and if you've gotten something to work with Svelte, consider contributing!
For more amazing Svelte projects, check out the [Svelte Society](https://sveltesociety.dev/), [Reddit](https://www.reddit.com/r/sveltejs/) and [Discord](https://discord.com/invite/yy75DKs)… and be sure to post your own!
## See you next month!
By the way, Svelte now has an [OpenCollective](https://opencollective.com/svelte)! All contributions and all expenses are published in our transparent public ledger. Learn who is donating, how much, where that money is going, submit expenses, get reimbursed and more!

@ -1,46 +0,0 @@
---
title: What's new in Svelte: November 2020
description: Slot forwarding fixes, SvelteKit for faster local development, and more from Svelte Summit
author: Daniel Sandoval
authorURL: https://desandoval.net
---
Welcome back to the "What's new in Svelte" series! This month, we're covering new features & bug fixes, last month's Svelte Summit and some stand-out sites and libraries...
## New features & impactful bug fixes
1. Destructuring Promises now works as expected by using the `{#await}` syntax
(**3.29.3**, [Example](https://svelte.dev/repl/3fd4e2cecfa14d629961478f1dac2445?version=3.29.3))
2. Slot forwarding (released in 3.29.0) should no longer hang during compilation (**3.29.3**, [Example](https://svelte.dev/repl/29959e70103f4868a6525c0734934936?version=3.29.3))
3. Better typings for the `get` function in `svelte/store` and on lifecycle hooks (**3.29.1**)
**What's going on in Sapper?**
Sapper got some new types in its `preload` function, which will make typing easier if you are using TypeScript. See the [Sapper docs](https://sapper.svelte.dev/docs#Typing_the_function) on how to use them. There also were fixes to `preload` links in exported sites. Route layouts got a few fixes too - including ensuring CSS is applied to nested route layouts. You can also better organize your files now that extensions with multiple dots are supported. (**0.28.10**)
For all the features and bugfixes see the CHANGELOGs for [Svelte](https://github.com/sveltejs/svelte/blob/master/CHANGELOG.md) and [Sapper](https://github.com/sveltejs/sapper/blob/master/CHANGELOG.md).
## [Svelte Summit](https://sveltesummit.com/) was Svelte-tacular!
- Rich Harris demoed the possible future of Svelte development in a talk titled "Futuristic Web Development". The not-yet-public project is called SvelteKit (name may change) and will bring a first-class developer experience and more flexibility for build outputs. If you want to get the full sneak-peek, [check out the video](https://www.youtube.com/watch?v=qSfdtmcZ4d0).
- 17 speakers made the best of the conference's virtual format... From floating heads to seamless demos, Svelte developers from every skill level will find something of interest in this year's [YouTube playlist](https://www.youtube.com/playlist?list=PL8bMgX1kyZThM1sbYCoWdTcpiYysJsSeu)
---
## Community Showcase
- [Svelte Lab](https://sveltelab.app/) showcases a variety of components, visualizations and interactions that can be achieved in Svelte. You can click into any component to see its source or edit it, using the site's built-in REPL
- [svelte-electron-boilerplate](https://github.com/hjalmar/svelte-electron-boilerplate) is a fast way to get up and running with a Svelte app built in the desktop javascript framework, Electron
- [React Hooks in Svelte](https://github.com/joshnuss/react-hooks-in-svelte) showcases examples of common React Hooks ported to Svelte.
- [gurlic](https://gurlic.com/) is a social network and internet experiment that is super snappy thanks to Svelte
- [Interference 2020](https://interference2020.org/) visualizes reported foreign interference in the 2020 U.S. elections. You can learn more about how it was built in [YYY's talk at Svelte Summit]()
- [jitsi-svelte](https://github.com/relm-us/jitsi-svelte) lets you easily create your own custom Jitsi client by providing out-of-the-box components built with Svelte
- [Ellx](https://ellx.io/) is part spreadsheet, part notebook and part IDE. It's super smooth thanks to Svelte 😎
- [This New Zealand news site](https://www.nzherald.co.nz/nz/election-2020-latest-results-party-vote-electorate-vote-and-full-data/5CFVO4ENKNQDE3SICRRNPU5GZM/) breaks down the results of the 2020 Parliamentary elections using Svelte
- [Budibase](https://github.com/Budibase/budibase) is a no-code app builder, powered by Svelte
- [Svelt-yjs](https://github.com/relm-us/svelt-yjs) combines the collaborative, local-first technology of Yjs with the power of Svelte to enable multiple users across the internet to stay in sync.
- [tabler-icons-svelte](https://github.com/benflap/tabler-icons-svelte) is a Svelte wrapper for over 850 free MIT-licensed high-quality SVG icons for you to use in your web projects.
## See you next month!
Got an idea for something to add to the Showcase? Want to get involved more with Svelte? We're always looking for maintainers, contributors and fanatics... Check out the [Svelte Society](https://sveltesociety.dev/), [Reddit](https://www.reddit.com/r/sveltejs/) and [Discord](https://discord.com/invite/yy75DKs) to get involved!

@ -1,103 +0,0 @@
---
title: What's the deal with SvelteKit?
description: We're rethinking how to build Svelte apps. Here's what you need to know
author: Rich Harris
authorURL: https://twitter.com/rich_harris
---
<aside><p>If you <em>didn't</em> attend Svelte Summit, you can catch up on the <a href="https://www.youtube.com/c/SvelteSociety/videos">Svelte Society YouTube page</a></p></aside>
If you attended [Svelte Summit](https://sveltesummit.com/) last month you may have seen my talk, Futuristic Web Development, in which I finally tackled one of the most frequently asked questions about Svelte: when will Sapper reach version 1.0?
The answer: never.
This was slightly tongue-in-cheek — as the talk explains, it's really more of a rewrite of Sapper coupled with a rebrand — but it raised a lot of new questions from the community, and it's time we offered a bit more clarity on what you can expect from Sapper's successor, SvelteKit.
<div class="max">
<figure style="max-width: 960px; margin: 0 auto">
<div style="height: 0; padding: 0 0 57.1% 0; position: relative; margin: 0 auto;">
<iframe style="position: absolute; width: 100%; height: 100%; left: 0; top: 0; margin: 0;" src="https://www.youtube-nocookie.com/embed/qSfdtmcZ4d0" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
<figcaption>'Futuristic Web Development' from <a href="https://sveltesummit.com/">Svelte Summit</a></figcaption>
</figure>
</div>
## What's Sapper?
[Sapper](https://sapper.svelte.dev) is an *app framework* (or 'metaframework') built on top of Svelte (which is a *component* framework). Its job is to make it easy to build Svelte apps with all the modern best practices like server-side rendering (SSR) and code-splitting, and to provide a project structure that makes development productive and fun. It uses *filesystem-based routing* (as popularised by [Next](https://nextjs.org/) and adopted by many other frameworks, albeit with some enhancements) — your project's file structure mirrors the structure of the app itself.
While the Svelte homepage and documentation encourages you to [degit](https://github.com/Rich-Harris/degit) the [sveltejs/template](https://github.com/sveltejs/template) repo to start building an app, Sapper has long been our recommended way to build apps; this very blog post is (at the time of writing!) rendered with Sapper.
## Why are we migrating to something new?
Firstly, the distinction between [sveltejs/template](https://github.com/sveltejs/template) and [sveltejs/sapper-template](https://github.com/sveltejs/sapper-template) is confusing, particularly to newcomers to Svelte. Having a single recommended way to start building apps with Svelte will bring enormous benefits: we simplify onboarding, reduce the maintenance and support burden, and can potentially begin to explore the new possibilities that are unlocked by having a predictable project structure. (This last part is deliberately vague because it will take time to fully understand what those possibilities are.)
Aside from all that, we've been tempted by the thought of rewriting Sapper for a while. This is partly because the codebase has become a little unkempt over the years ([Sapper started in 2017](/blog/sapper-towards-the-ideal-web-app-framework)), but mostly because the web has changed a lot recently, and it's time to rethink some of our foundational assumptions.
## How is this new thing different?
The first of those foundational assumptions is that you need to use a module bundler like [webpack](https://webpack.js.org/) or [Rollup](http://rollupjs.org/) to build apps. These tools trace the dependency graph of your application, analysing and transforming code along the way (turning Svelte components to JS modules, for example), in order to create bundles of code that can run anywhere. As the original creator of Rollup, I can attest that it is a surprisingly complex problem with fiendish edge cases.
You certainly needed a bundler several years ago, because browsers didn't natively support the `import` keyword, but it's much less true today. Right now, we're seeing the rise of the *unbundled development* workflow, which is radically simpler: instead of eagerly bundling your app, a dev server can serve modules (converted to JavaScript, if necessary) *on-demand*, meaning startup is essentially instantaneous however large your app becomes.
[Snowpack](https://www.snowpack.dev/) is at the vanguard of this movement, and it's what powers SvelteKit. It's astonishingly fast, and has a beautiful development experience (hot module reloading, error overlays and so on), and we've been working closely with the Snowpack team on features like SSR. The hot module reloading is particularly revelatory if you're used to using Sapper with Rollup (which has never had first-class HMR support owing to its architecture, which prioritises the most efficient output).
That's not to say we're abandoning bundlers altogether. It's still essential to optimise your app for production, and SvelteKit uses Rollup to make your apps as fast and lean as they possibly can be (which includes things like extracting styles into static `.css` files).
The other foundational assumption is that a server-rendered app needs, well, a server. Sapper effectively has two modes — `sapper build`, which creates a standalone app that has to run on a Node server, and `sapper export` which bakes your app out as a collection of static files suitable for hosting on services like GitHub Pages.
Static files can go pretty much anywhere, but running a Node server (and monitoring/scaling it etc) is less straightforward. Nowadays we're witnessing a shift towards *serverless platforms*, in which you as the app author don't need to think about the server your code is running on, with all the attendant complexity. You can get Sapper apps running on serverless platforms, thanks to things like [vercel-sapper](https://github.com/thgh/vercel-sapper), but it's certainly not what you'd call idiomatic.
<aside><p>It'll still be possible to create both Node apps and fully pre-rendered (aka exported) sites</a></p></aside>
SvelteKit fully embraces the serverless paradigm, and will launch with support for all the major serverless providers, with an 'adapter' API for targeting any platforms that we don't officially cater to. In addition, we'll be able to do partial pre-rendering, which means that static pages can be generated at build time but dynamic ones get rendered on-demand.
## When can I start using it?
If you're feeling brave, you can start right now:
```bash
npm init svelte@next
```
This will scaffold a new project and install the `@sveltejs/kit` CLI, which provides the tools for developing and building an app.
We don't recommend it though! There are no docs, and we won't be able to offer any form of support. It's also likely to break often.
The work is being done in a private monorepo while we're still in exploration mode. Our plan is to get a public beta ready and announce it here once we've closed a few issues — the repo itself will remain private at that time, but we'll create a place to collect feedback from the YOLO crowd. After that, we'll work towards a 1.0 release which will involve opening the repo up.
I'm not going to make any firm promises about timings, because I don't like to break promises. But I *think* we're talking about weeks rather than months.
## What if I don't want to use SvelteKit?
You won't have to — it will always be possible to use Svelte as a standalone package or via a bundler integration like [rollup-plugin-svelte](https://github.com/sveltejs/rollup-plugin-svelte). We think it's essential that you can bend Svelte to fit your workflow, however esoteric, and use third-party app frameworks like [Elder.js](https://github.com/Elderjs/elderjs), [Routify](https://routify.dev/), [Plenti](https://plenti.co/), [Crown](https://crownframework.com/), [JungleJS](https://www.junglejs.org/) and others.
## TypeScript?
Don't worry, we won't launch without full TypeScript support.
## How can I migrate my existing Sapper apps?
For the most part, it should be relatively straightforward to migrate a Sapper codebase.
There are some unavoidable changes (being able to run on serverless platforms means we need to replace custom `server.js` files and `(req, res) => {...}` functions with more portable equivalents), and we're taking the opportunity to fix a few design flaws, but on the whole a SvelteKit app will feel very familiar to Sapper users.
Detailed migration guides will accompany the 1.0 launch.
## How can I contribute?
Keep your eyes peeled for announcements about when we'll launch the public beta and open up the repo. (Also, blog post TODO but I would be remiss if I didn't mention that we now have an [OpenCollective](https://opencollective.com/svelte) where you can contribute financially to the project if it's been valuable to you. Many, many thanks to those of you who already have.)
## Where can I learn more?
Follow [@sveltejs](https://twitter.com/sveltejs) and [@SvelteSociety](https://twitter.com/SvelteSociety) on Twitter, and visit [svelte.dev/chat](https://svelte.dev/chat). You should also subscribe to [Svelte Radio](https://www.svelteradio.com/), where Kevin and his co-hosts will grill me about this project on an upcoming episode (and between now and next week when we record it, [reply to this Twitter thread](https://twitter.com/Rich_Harris/status/1323376048571121665) with your additional questions).

@ -1,71 +0,0 @@
---
title: What's new in Svelte: December 2020
description: Better tooling, export maps and improvements to slots and context
author: Daniel Sandoval
authorURL: https://desandoval.net
---
It's the last "What's new in Svelte" of the year and there's lots to celebrate! This month's coverage includes updates from `rollup-plugin-svelte`, `Sapper` and `SvelteKit` and a bunch of showcases from the Svelte community!
## New features & impactful bug fixes
1. `$$props`, `$$restProps`, and `$$slots` are all now supported in custom web components (**3.29.5**, [Example](https://svelte.dev/repl/ad8e6f39cd20403dacd1be84d71e498d?version=3.29.5)) and `slot` components now support spread props: `<slot {...foo} />` (**3.30.0**)
2. A new `hasContext` lifecycle function makes it easy to check whether a `key` has been set in the context of a parent component (**3.30.0** & **3.30.1**, [Docs](https://svelte.dev/docs#hasContext))
3. There is now a new `SvelteComponentTyped` class which makes it easier to add strongly typed components that extend base Svelte components. Component library and framework authors rejoice! An example: `export class YourComponent extends SvelteComponentTyped<{aProp: boolean}, {click: MouseEvent}, {default: {aSlot: string}}> {}` (**3.31.0**, [RFC](https://github.com/sveltejs/rfcs/pull/37))
4. Transitions within `{:else}` blocks should now complete successfully (**3.29.5**, [Example](https://svelte.dev/repl/49cef205e5da459594ef2eafcbd41593?version=3.29.5))
5. Svelte now includes an export map, which explicitly states which files can be imported from its npm package (**3.29.5** with some fixes in **3.29.6**, **3.29.7** and **3.30.0**)
6. `rollup-plugin-svelte` had a new [7.0.0 release](https://github.com/sveltejs/rollup-plugin-svelte/blob/master/CHANGELOG.md). The biggest change is that the `css` option was removed. Users who were using that option should add another plugin like `rollup-plugin-css-only` as demonstrated [in the template](https://github.com/sveltejs/template/blob/5b1135c286f7a649daa99825a077586655051649/rollup.config.js#L48)
## What's going on in Sapper?
Lots of new TypeScript definition improvements to make editing Sapper apps even easier! CSS for dynamic imports also should now work in `client.js` files. (Unreleased)
## What's the deal with SvelteKit?
We're glad you asked! If you didn't catch Rich's blog post from early last month, [you can find it here](https://svelte.dev/blog/whats-the-deal-with-sveltekit)!
For all the features and bugfixes see the CHANGELOGs for [Svelte](https://github.com/sveltejs/svelte/blob/master/CHANGELOG.md) and [Sapper](https://github.com/sveltejs/sapper/blob/master/CHANGELOG.md).
---
## Community Showcase
**Apps & Sites**
- [narration.studio](https://narration.studio/) (Chrome Only) is an automatic in-browser audio recording & editing platform for voice over narration.
- [Vippet](https://vippet.netlify.app/) is a video recording and editing tool for the browser.
- [Pattern Monster](https://pattern.monster/) is a simple online pattern generator to create repeatable SVG patterns.
- [Plant-based diets](https://planetbaseddiets.panda.org/) is a website from the World Wildlife Foundation (WWF) built with Svelte.
- [johnells.se](https://www.johnells.se/) is a Swedish fashion e-commerce site, built with [Crown](https://crownframework.com/) - a Svelte-powered framework.
- [sentence-length](https://sentence-length.netlify.app/) is a learning and analysis tool to show how some authors play with different lengths, while others stick with one.
- [svelte-presenter](https://github.com/stephane-vanraes/svelte-presenter) lets you quickly make good looking presentations using Svelte and mdsvex.
**Demos**
- [u/loopcake got SSR working in Java Spring Boot](https://www.reddit.com/r/sveltejs/comments/jkh5up/svelte_ssr_but_its_java_spring_boot_and_its_native/) for all the Java shops out there looking to render Svelte server-side.
- [svelte-liquid-swipe](https://github.com/tncrazvan/svelte-liquid-swipe) shows off a fancy interaction pattern using svg paths.
- [Crossfade Link Animation](https://svelte.dev/repl/7f68e148caf04b2787bb6f296208f870?version=3.29.7) demonstrates how to animate between navigation links using a crossfade (made by Blu, from the Discord community)
- [Clip-Path Transitions](https://svelte.dev/repl/b5ad281ae8024b629b545c70c9e8764d?version=3.29.7) showcases how to use clip paths and custom transitions to create magical in-and-out transitions (made by Faber, from the Discord community)
**Learning Resources**
- [lihautan](https://www.youtube.com/channel/UCbmC3HP3FaAFdcZkui8YoMQ/featured) has been making easy-to-follow videos to share his in-depth knowledge of Svelte.
- [Lessons From Building a Static Site Generator](https://nicholasreese.com/lessons-from-building-a-static-site-generator/) shares the backstory and thinking behind Elder.js - and the design decision made along the way.
- [Svelte Tutorial and Projects Course ](https://www.udemy.com/course/svelte-tutorial-and-projects-course/) is a udemy course by John Smilga where students learn Svelte.js by building interesting projects.
- [Building Pastebin on IPFS - with FastAPI, Svelte, and IPFS](https://amalshaji.wtf/building-pastebin-on-ipfs-with-fastapi-svelte-and-ipfs) explains how to make a distributed pastebin-like application.
**Components, Libraries & Tools**
- [svelte-crossword](https://russellgoldenberg.github.io/svelte-crossword/) is a customizable crossword puzzle component for Svelte.
- [svelte-cloudinary](https://github.com/cupcakearmy/svelte-cloudinary) makes it easy to integrate Cloudinary with Svelte (including Typescript and SSR support)
- [Svelte Nova](https://extensions.panic.com/extensions/sb.lao/sb.lao.svelte-nova/) extends the new Nova editor to support Svelte
- [saos](https://github.com/shiryel/saos) is a small svelte component to animate your elements on scroll.
- [Svelte-nStore](https://github.com/lacikawiz/svelte-nStore) is a general purpose store replacement that fulfills the Svelte store contract and adds getter and calculation features.
- [svelte-slimscroll](https://github.com/MelihAltintas/svelte-slimscroll) is a Svelte Action that transforms any div into a scrollable area with a nice scrollbar.
- [svelte-typewriter](https://github.com/henriquehbr/svelte-typewriter) is a simple and reusable typewriter effect for your Svelte applications
- [svelte-store-router](https://github.com/zyxd/svelte-store-router) is a store-based router for Svelte that suggests that routing is just another global state and History API changes are just an optional side-effects of this state.
- [Routify](https://routify.dev/blog/routify-2-released) just released version 2 of its Svelte router.
- [svelte-error-boundary](https://www.npmjs.com/package/@crownframework/svelte-error-boundary) provides a simple error boundary component for Svelte that can be can be used with both DOM and SSR targets.
- [svelte2dts](https://www.npmjs.com/package/svelte2dts) generates d.ts files from svelte files, creating truly sharable and well typed components.
## See you next month!
Got an idea for something to add to the Showcase? Want to get involved more with Svelte? We're always looking for maintainers, contributors and fanatics... Check out the [Svelte Society](https://sveltesociety.dev/), [Reddit](https://www.reddit.com/r/sveltejs/) and [Discord](https://discord.com/invite/yy75DKs) to get involved!
That's all for the year, folks! See you in January 😎

@ -1,86 +0,0 @@
---
title: What's new in Svelte: January 2021
description: A Svelte-packed showcase to kick-off the new year!
author: Daniel Sandoval
authorURL: https://desandoval.net
---
Happy new year from Svelte! In the last month we made progress on Sapper's upcoming release, fine-tuned our `SvelteComponent` typings, and have seen some amazing apps, sites, and libraries coming out in the showcase.
## What's changed in Svelte?
A new minor release replaces the `SvelteComponent` class with a `SvelteComponentTyped` class. This renaming should help with backwards compatibility. We've updated [last month's blog post](https://svelte.dev/blog/whats-new-in-svelte-december-2020) to avoid any confusion with the name change.
If you're using `SvelteComponent` or the new `SvelteComponentTyped` in your project or library, let us know what you're using it for and we'll add it to the showcase!
## What's going on in Sapper?
More quality of life features are landing in the upcoming release every day. `0.29.0` will include new TypeScript definitions, fixes to scroll tracking and prefetching behavior, and improvements to the runtime router to support encoded query parameters.
If you're upgrading from 0.28.x, check out [the migration guide](https://sapper.svelte.dev/migrating/#0_28_to_0_29) for steps on updating to Sapper 0.29.
## Is SvelteKit ready yet?
To avoid too much churn during development, SvelteKit is still being worked on in a private repo. There will be an announcement on the Discord, blog and Twitter when it's ready for a larger group of users and contributors.
In the meantime, you can explore the current build by running `npm init svelte@next` from your command line.
As cautioned in _[What's the deal with SvelteKit?](https://svelte.dev/blog/whats-the-deal-with-sveltekit)_, there are no docs or support available yet... So use at your own risk / for your own enjoyment!
---
## Community Showcase
**Apps & Sites**
- [manitu.me](https://manitu.me/) is a background sound / pomodoro timer for focus and relaxation
- [Answer Socrates](https://answersocrates.com/) helps you find trending questions on the internet so that you can write the most relevant blog post, tweet, or billboard
- [multris](https://multris.s1h.org/) is a multiplayer Tetris game. You can read about its development [here](https://blog.s1h.org/svelte-multiplayer-game/)
- [weather-ab](https://github.com/ganochenkodg/weather-ab) compares the archive of weather in different cities of the world. Indispensable for people thinking about migration
- [Game Nibs](https://gamenibs.com/) is a platform for gamers to find and share concise bite-sized bits of gaming advice, tips, tricks, screenshots, builds, and much more
- [Ora](https://github.com/cupcakearmy/ora) is an open source website tracking and limiting tool for Chrome and Firefox
- [vscode-dms](https://github.com/techsyndicate/vscode-dms) is a group direct messaging chat app for VSCode
- [Zero.2](https://zero.oleksandrdemian.tech/) is a math-based challenge game where you try to get to zero as quickly as possible
- [Octave Compass](https://octavecompass.com/2741) is a chord table and scale explorer for many popular musical scales
- [Infinite Walking Bass Generator 2](https://github.com/elialbert/infinitewalkingbass2) is an online music player that generates a unique walking bass line
- [ListenAddict](https://www.listenaddict.com/) is a site that notifies you whenever a person has a new talk/interview on podcast
**Demos, Libraries & Components**
- [svelte-tiny-virtual-list](https://github.com/Skayo/svelte-tiny-virtual-list) speeds up long lists by only rendering visible items
- [svelte-query](https://github.com/TanStack/svelte-query) is a collection of helpful hooks for managing, caching and syncing asynchronous and remote data
- [svelte-previous](https://github.com/bryanmylee/svelte-previous) is a svelte store to remember previous values - helpful for transitions or a quick undo stack
- [Let's Build a Confetti Cannon](https://varun.ca/confetti/) explains how to build a particle system and integrate a Canvas based animation into a larger application
- [svelte-micro](https://github.com/ayndqy/svelte-micro) is a one-component router
- [svelte-standalone-router](https://github.com/hjalmar/svelte-standalone-router) is a standalone router with an API based on [standalone-router](https://github.com/hjalmar/standalone-router)
- [svelte-datepicker](https://github.com/beyonk-adventures/svelte-datepicker) is a datepicker component with variations for time selection, date ranges and responsive themes
- [svelte-slimscroll](https://github.com/MelihAltintas/svelte-slimscroll) is a action for Svelte.js, which can transforms any div into a scrollable area with a nice scrollbar.
- [Svelte Zoomable](https://svelte.dev/repl/58dfe87756ee4db897c281b52fdef7b7?version=3.31.0) is a custom transition with a nice zoom effect
**Have a component you'd like to share?** Check out the [Components](https://sveltesociety.dev/components) page on the Svelte Society site. You can contribute by making [a PR to this file](https://github.com/svelte-society/sveltesociety.dev/blob/master/src/pages/components/components.json).
**Learning Resources**
- [Using Svelte to create a scroll video effect](https://blog.koenvangilst.nl/tutorial-svelte-scroll-video/) showcases how the `bind` command can be used to create a cool scroll video effect with very little code
- [How to make a flappybird game in svelte and typescript](https://www.youtube.com/watch?v=nhrYBoVI8pQ) is a video tutorial including docs and code for reference
- [Accessible Svelte Transition](https://www.youtube.com/watch?v=QK_QuRL7nSo&feature=youtu.be) walks through `prefers-reduced-motion` to make svelte transitions more accessible
- [Svelte's module scripts explained](https://codechips.me/svelte-module-scripts-explained/) is a great introduction to the module context, a common Sapper pattern
- [Awesome Svelte](https://github.com/TheComputerM/awesome-svelte#readme) is a curated list of Svelte resources
- [.NET Core and Svelte](https://dev.to/cainux/net-core-and-svelte-f8o) explains how to get Svelte up and running with .NET Core
- [A la découverte de Svelte JS](https://www.youtube.com/watch?v=SLpx1Y8e1ek&list=PLff5I1miao9ZEUhpqkrOx7k8RGAZt-nm9) is a svelte tutorial series in French!
- [Svelte for React Developers](https://soshace.com/svelte-for-react-developers/) explains Svelte's core concepts to folks who are used to React
- [Building a Svelte Static Website with Smooth Page Transitions](https://www.youtube.com/watch?v=dvPfmcGtmrI&feature=emb_title) shows how to build a static website with Svelte and add smooth page transitions using Three.js and GSAP.
- [Using Apollo Client in Sapper](https://bjornlu.com/blog/using-apollo-client-in-sapper/) explains the "simplest" solutions to integrate the Apollo query client into Sapper
- [Reactive web apps with Crystal + Svelte](https://www.youtube.com/watch?v=i1xjLd6z7BU) explores how to build full-stack, server-rendered Svelte apps with a [Crystal](https://crystal-lang.org) backend
**Related Projects**
- [Snowpack's v3 release candidate](https://www.snowpack.dev/posts/2020-12-03-snowpack-3-release-candidate) is out now in preparation for a January 6 release date. Check out the [Getting Started with Svelte](https://www.snowpack.dev/tutorials/svelte) for more info on how to use Snowpack.
- [Uppy](https://uppy.io/blog/2020/12/1.24/), the open source file uploader, announced Svelte support in its new version 1.24
## See you next month!
Want to add your work to the Showcase? Want to contribute to Svelte? Check out the [Svelte Society](https://sveltesociety.dev/), [Reddit](https://www.reddit.com/r/sveltejs/) and [Discord](https://discord.com/invite/yy75DKs) to get involved!

@ -1,86 +0,0 @@
---
title: What's new in Svelte: February 2021
description: Integrations and improvements at lightning speed...
author: Daniel Sandoval
authorURL: https://desandoval.net
---
With the shortest month of the year coming up, Svelte maintainers and community members alike have been busy this last month from big changes in `svelte-loader`, `prettier-plugin-svelte`, `rollup-plugin-svelte`, and `language-tools` to steady progress in Sapper and `svelte-preprocess`. Meanwhile, lots of folks have been busy integrating Svelte with other popular frameworks.
## New compiler features
- Aria roles from the [WAI-ARIA Graphics Module](https://www.w3.org/TR/graphics-aria-1.0/#role_definitions) are now recognized as valid aria roles in Svelte components (**3.31.1**)
- Compiler warnings for the common React attributes, `className` and `htmlFor`, now make it easier to port React components to Svelte (**3.31.1**)
Have a suggestion for a compiler feature or want to help implement new features/bug fixes? Check out the ["triage: good first issue" tag for Svelte](https://github.com/sveltejs/svelte/issues?q=is%3Aopen+is%3Aissue+label%3A%22triage%3A+good+first+issue%22)
## New bits in language-tools
- User disabled auto import suggestions no longer show in VS Code (**103.0.0**)
- Renaming a variable is now safer with smart additions of a prefix/suffix to renamed variables (**104.0.0**)
- Semantic (token) highlighting for TypeScript users lets theme makers apply semantic styling in their themes, if they support it (**104.0.0**)
- "Extract Component" has been added to the context menu - allowing you to extract components out of files without having to open the command window to type "Svelte: Extract Component" (**104.0.0**)
- The VS Code extension now listens to JavaScript/TypeScript file changes - you no longer need to save the files for the changes to be noticed (**104.1.0**)
For the complete list of changes, check out the language-tools [Releases page](https://github.com/sveltejs/language-tools/releases).
A great way to try the language tools is to download the [Svelte Extension for VSCode](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). This extension provides syntax highlighting and rich intellisense for Svelte components in VS Code, using the svelte language server. Check your editor's extension sources to see if there's a Svelte plugin for your IDE or build your own (see [coc-svelte](https://github.com/coc-extensions/coc-svelte) for example)!
## Big improvements across the Svelte ecosystem
- [svelte-loader](https://github.com/sveltejs/svelte-loader) released a major version, 3.0.0 - featuring Webpack 5 and Node 14 support, better hot reloading, and new `compilerOptions` to match `rollup-plugin-svelte`. Breaking changes include dropping Svelte 2 and Node 8 support. [More info in the changelog](https://github.com/sveltejs/svelte-loader/blob/master/CHANGELOG.md)
- [rollup-plugin-svelte](https://github.com/sveltejs/rollup-plugin-svelte) is now at version 7.x - with support for relative filenames, better handling of sourcemaps, and consistent `compilerOptions`. Be sure to [checkout the changelog](https://github.com/sveltejs/rollup-plugin-svelte/blob/master/CHANGELOG.md) for breaking changes when upgrading
- [svelte-preprocess](https://github.com/sveltejs/svelte-preprocess) iterated through some 4.6.x releases this month to improve postcss and scss handling and fix sourcemap transformation for typescript users. [More info in the changelog](https://github.com/sveltejs/svelte-preprocess/blob/main/CHANGELOG.md)
- [Sapper](https://github.com/sveltejs/sapper) got some improvements in scroll tracking and handling encoding query parameters. Dynamic imports also now work as expected in browsers that don't support ES modules. These changes from 0.29.0 and a step-by-step migration guide can be found [in the changelog](https://github.com/sveltejs/sapper/blob/master/CHANGELOG.md)
- [prettier-plugin-svelte](https://github.com/sveltejs/prettier-plugin-svelte) version 2 was released. It received an overhaul and comes with a rewrite of the HTML formatting. The output is now much more in line with how standard Prettier formats HTML. Better defaults for `svelteBracketNewLine` and `options-scripts-markup-styles` should now match how the majority of users like to order the code blocks. Additionally, Prettier's `htmlWhitespaceSensitivity` setting is now supported. [More info in the changelog](https://github.com/sveltejs/prettier-plugin-svelte/blob/master/CHANGELOG.md)
New changes to the Svelte Society website include [a new cheat sheet](https://sveltesociety.dev/cheatsheet) for easy access to useful code patterns and some smaller visual fixes across the site. **Want to help make the Svelte Society website ready for prime time**? [Checkout the GitHub repo](https://github.com/svelte-society/sveltesociety.dev) to get started!
---
## Community Showcase
**Apps & Sites**
- [The official German vaccination dashboard](https://impfdashboard.de/) tracks the current COVID vaccine rollout and features some well-done dataviz.
- [La neuva era de la educatión conectada](https://elfuturoesapasionante.vodafone.es/especiales/educacion-conectada/) is a Vodaphone site that highlights the ways that technology and COVID-19 has changed the education landscape
- [sho.rest](https://github.com/Melonai/shorest) is a self-hostable url shortener
- [night.fm](https://night.fm/) is a cyberpunk-themed radio station
**Demos, Libraries & Components**
- [Svelte Reactive Debugger](https://addons.mozilla.org/en-US/firefox/addon/svelte-reactive-debugger/) is a way to monitor Svelte reactive statements in Firefox devtools
- [svelte-actions](https://github.com/sw-yx/svelte-actions) is a set of prototype Svelte actions for inclusion into official actions in future. [See RFC](https://github.com/sveltejs/rfcs/pull/24) and [Discuss High Level Policy](https://github.com/sw-yx/svelte-actions/issues/7).
- [This css grid gallery](https://svelte.dev/repl/3a1b7fae13b242fe9cd4a4f7aa092fa4?version=3.31.2) made by @joja (in the Svelte Discord) features grid transitions based on a user's mouse position
- [Patchcab](https://github.com/spectrome/patchcab) is a modular Eurorack style synthesizer made with Web Audio.
- [svelte-knob](https://github.com/MelihAltintas/svelte-knob) is a knob control to help with speedometer-style visualization
- [descent-ripple](https://github.com/micha-lmxt/descent-ripple) is a highly customizable javascript ripple animation for buttons
- [makeItSnow](https://github.com/florianlouvet/make-it-snow/blob/main/makeItSnowAction.js) is a Svelte action made by @MrPoule (in the Svelte Discord) that can be used to add ❄snow❄ to any component ([Demo](https://svelte.dev/repl/de5223beb45540a5a11c9bd7b318304f?version=3.31.2))
- [svelte-video-player](https://github.com/meigo/svelte-video-player) is a customizable `VideoPlayer` component
- [svelte-readonly](https://github.com/Crisfole/svelte-readonly) is a very small store that exposes only a readable interface.
**New Integrations & Starters**
- [svelte-derver-starter](https://github.com/AlexxNB/svelte-derver-starter) is a starter for baking fullstack application with the client based on Svelte and server side powered by Derver.
- [eleventy-plugin-embed-svelte](https://github.com/shalomscott/eleventy-plugin-embed-svelte) makes it easy to embed Svelte components into an 11ty site.
- [svelte-tailwind-extension-boilerplate](https://github.com/kyrelldixon/svelte-tailwind-extension-boilerplate) is a good foundation for a Chrome extension using either JavaScript or TypeScript, Svelte for the frontend, Tailwind CSS for styling, Jest for testing, and Rollup as the build system.
- [snowpack-ui](https://github.com/rajasegar/snowpack-ui) lets you run & manage Snowpack projects from the browser instead of the terminal
- [Svelte for Appwrite](https://dev.to/torstendittmann/svelte-for-appwrite-4fkg) explains how to integrate with Appwrite, a self-hosted Firebase alternative [Github Repo](https://github.com/appwrite/sdk-for-svelte)
- [here-maps-svelte](https://github.com/peopledrivemecrazy/here-maps-svelte) makes it easy to include HERE maps in a Svelte app
- [p5-svelte](https://github.com/tonyketcham/p5-svelte) is an absolutely dead simple way of tossing the creative coding/sketching tool, p5, into a project
- [svelte-windicss-preprocess](https://github.com/voorjaar/svelte-windicss-preprocess) is a Svelte preprocessor to compile tailwindcss at build time based on windicss compiler
- [MitzaCoder/svelte-boilerplate](https://github.com/MitzaCoder/svelte-boilerplate) features configurations for Typescript, TailwindCSS, IE11 compatibility (with Babel) and lazy loaded modules.
**Want to share your Svelte Component with the world?** Head over to the [Components](https://sveltesociety.dev/components) page on the Svelte Society site. You can contribute by making [a PR to this file](https://github.com/svelte-society/sveltesociety.dev/blob/master/src/pages/components/components.json).
**Learning Resources**
- [lihautan's Svelte Actions Playlist](https://www.youtube.com/watch?v=ciaMT_MswzE&list=PLoKaNN3BjQX3Gl14MBygFf8buPIw9pAeK) teaches how actions work and how they can help solve common problems when developing Svelte applications
- [One-click Portfolio/Personal blog generator from dev.to API ](https://dev.to/shriji/one-click-portfolio-personal-blog-generator-from-dev-to-api-3apb) walks through creating a Sapper site that also fetches your articles from DEV.to using the API
- [How to Code a VSCode Extension](https://www.youtube.com/watch?v=a5DX5pQ9p5M) features Svelte as a way to render a custom UI within VSCode
- [This YouTube series on Plenti](https://www.youtube.com/watch?v=wyNC7R_VVyQ&list=PLbWvcwWtuDm12y3Hye6oKDwI2gAS0ccHW) walks through the new static site generator in detail
## See you next month!
Want to add your work to the Showcase? Want to contribute to Svelte? Check out the [Svelte Society](https://sveltesociety.dev/), [Reddit](https://www.reddit.com/r/sveltejs/) and [Discord](https://discord.com/invite/yy75DKs) to get involved!

@ -1,104 +0,0 @@
---
title: What's new in Svelte: March 2021
description: Call for Svelte Summit Speakers! Improved SSR, non-HTML5 compilation targets, and ESLint TypeScript support
author: Daniel Sandoval
authorURL: https://desandoval.net
---
Lots to cover this month with releases from across the Svelte ecosystem. Most importantly, Svelte Summit Spring 2021 has an [Open Call for Speakers](https://sessionize.com/svelte-summit-spring-2021). **The deadline is March 14** so if you have an idea for a talk, submit it now!
Let's dive into the news 🐬
## What's new in `sveltejs/svelte`
* SSR store handling has been reworked to subscribe and unsubscribe as in DOM mode. SSR stores should work much more consistently now (**3.31.2**, see [custom stores](https://svelte.dev/examples#custom-stores) and [Server-side component API ](https://svelte.dev/docs#Server-side_component_API))
* Multiple instances of the same action are now allowed on an element (**3.32.0**, [example](https://svelte.dev/repl/01a14375951749dab9579cb6860eccde?version=3.32.0))
* The new `foreign` namespace should make it easier for alternative compile targets (like Svelte Native and SvelteGUI) by disabling certain HTML5-specific behaviour and checks (**3.32.0**, [more info](https://github.com/sveltejs/svelte/pull/5652))
* Support for inline comment sourcemaps in code from preprocessors (**3.32.0**)
* Destructured defaults are now allowed to refer to other variables (**3.33.0**, [example](https://svelte.dev/repl/0ee7227e1b45465b9b47d7a5ae2d1252?version=3.33.0))
* Custom elements will now call `onMount` functions when connecting and clean up when disconnecting (**3.33.0**, checkout [this PR](https://github.com/sveltejs/svelte/pull/4522) for an interesting conversation on how folks are using Svelte with Web Components)
* A `cssHash` option has been added to the compiler options to control the classname used for CSS scoping (**3.34.0**, [docs](https://svelte.dev/docs#svelte_compile))
* Continued improvement to Typescript definitions
For a complete list of changes, including bug fixes and links to PRs, check out [the CHANGELOG](https://github.com/sveltejs/svelte/blob/master/CHANGELOG.md)
## New from `sveltejs/language-tools`
- For language server clients that don't support `didChangeWatchedFiles`, a fallback file watcher will be used instead
- New highlighting rules for store accessors and element directives (like `bind:` and `class:`)
- HTML tags can now be renamed together
- Mustache tags parsing is now more robust and will provide better intellisense in more situations
Haven't tried the language-tools yet? Check out [Svelte Extension for VSCode](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode) or find a plugin for your favorite IDE!
## Other changes from `sveltejs/*`
- [eslint-plugin-svelte3](https://github.com/sveltejs/eslint-plugin-svelte3) now supports TypeScript as of 3.1.0
- [prettier-plugin-svelte](https://github.com/sveltejs/prettier-plugin-svelte/) released a number of minor versions to address whitespace and comment trimming issues.
- [svelte-preprocess](https://github.com/sveltejs/svelte-preprocess/) bug fixes this month include fixes to postcss transformations and support for both v2 and v3 of `postcss-load-config`
- [sapper](https://github.com/sveltejs/sapper/)'s 0.29.1 release fixes some bad imports in type definitions, updates typings to be compatible with express/polka, and restores hashing of all CSS file names.
---
## Community Showcase
**Apps & Sites**
- [Tracking the Coronavirus](https://www.nytimes.com/interactive/2021/us/new-york-city-new-york-covid-cases.html) from NYTimes is an example of SvelteKit in production
- [Budibase](https://github.com/Budibase/budibase) is an open-source low-code platform, helping developers and IT professionals build, automate, and ship internal tools 50x faster on their own infrastructure.
- [Track the Parcel](https://tracktheparcel.com/) is a one-stop tool for tracking parcel status with all major package shippers.
- [Memo](https://sendmemo.app/features/) is a replacement for email that uses Svelte for modern messaging
- [Userscripts Safari](https://github.com/quoid/userscripts) is an open-source userscript editor for Safari... a native Svelte app for Mac OS!
- [SVGX](https://svgx.app/) is "the desktop SVG asset manager designers and developers wished they had."
- [Armoria](https://azgaar.github.io/Armoria/) is a procedural heraldry generator and editor
- [FictionBoard](https://www.fictionboard.com) is a virtual table top (VTT) platform that just released fillable and responsive character sheets
- [Castles & Crusades Treasure Generator](https://treasure.playaheadgames.com/) is a treasure generator for the table top RPG: Castles and Crusades.
- [NESBit Studio](https://jensa.org/NESBitStudio-web/graphics/spritesheets) is a toolkit to help the development of homebrew NES games
- [ElectroBlocks](https://electroblocks.org/) is an online Arduino IDE with a built-in simulator (Chrome Only)
- [Goblin.life](https://store.steampowered.com/app/552180/GoblinLife/) is a 3D world builder whose UI is built with Svelte
- [farmbox](https://farmbox.ae/) is a UAE-based grocery delivery services
- [heroeswearmasks.fun](https://heroeswearmasks.fun/) is a client-side machine learning tool that determines whether or not you're wearing a mask.
- [weatherify](https://brdtheo-weatherify.netlify.app/) is a very pretty (and [open source](https://github.com/brdtheo/weatherify)) weather app
- [DSN Live](https://dsn-live.netlify.app/#/) lets you monitor connections between NASA/JPL and interplanetary spacecraft missions in real time.
**Demos, Libraries, Tools & Components**
- [spc](https://github.com/khang-nd/spc) is a special characters picker component for the web
- [svelte-injector](https://www.npmjs.com/package/svelte-injector) lets you inject Svelte components in React, Angular, Vue, jQuery, Vanilla JS.
- [Felte](https://felte.dev/) is a form library for Svelte with simple validation reporting.
- [svelte-use-form](https://github.com/noahsalvi/svelte-use-form#readme) is form library that "is easy to use and has 0 boilerplate."
- [Formula](https://formula.svelte.codes/) provides "Zero Configuration Reactive Forms for Svelte."
- [Houdini](https://github.com/AlecAivazis/houdini) is "the disappearing GraphQL client built for Sapper and Sveltekit."
- [svelte-split-pane](https://www.reddit.com/r/sveltejs/comments/leoe33/sveltesplitpane/) is a draggable split pane component
- [svelte-virtualized-auto-sizer](https://github.com/micha-lmxt/svelte-virtualized-auto-sizer) is a high-order component that automatically adjusts the width and height of a single child.
- [svelte-window](https://github.com/micha-lmxt/svelte-window) are components for efficiently rendering large, scrollable lists and tabular data.
- [Svelte Persistent store](https://github.com/MacFJA/svelte-persistent-store) is a Svelte store that keep its value through pages and reloads
- [Svelte Dark](https://marketplace.visualstudio.com/items?itemName=NickScialli.svelte-dark) is a VSCode theme inspired by the svelte.dev REPL
- [Import Cost](https://marketplace.visualstudio.com/items?itemName=wix.vscode-import-cost) has been updated to support Svelte libraries and help developers keep their bundle size under control.
- [Tree-sitter-svelte](https://github.com/Himujjal/tree-sitter-svelte) provides tree-sitter grammar for svelte
- [Svelte Ripple](https://svelte.dev/repl/b73224a0fd4248178e3eab41943d41a9?version=3.31.2) is a Material Design ripple effect that doesn't depend on `@material/ripple` (made by @karakara in the Svelte Discord)
- [Analog SVG Clock](https://svelte.dev/repl/270e83f43e7a48918d8f2d497760904f?version=3.32.1) is a great example of easing functions (made by @tonmcg in the Svelte Discord)
- [Console Log Styler](https://svelte.dev/repl/11f609d0d90746f08da6d3d90bba84fc?version=3.32.0) lets you generate a styled console log using pseudo HTML and CSS (made by @EmNudge in the Svelte Discord)
- [svelte-heroicons](https://github.com/martinse/svelte-heroicons) is a handy wrapper for the Heroicons icon library
- [supabase-ui-svelte](https://github.com/joshnuss/supabase-ui-svelte) are UI components for Supabase authentication
**Have your own Svelte Component to share?** Check out the [Components](https://sveltesociety.dev/components) page on the Svelte Society site. You can contribute by making [a PR to this file](https://github.com/svelte-society/sveltesociety.dev/blob/master/src/pages/components/components.json).
**Learning Resources & Starters**
- [The **unofficial** SvelteKit docs](https://sk-incognito.vercel.app/learn/what-is-sveltekit) were built using SvelteKit and are [open for contributions](https://github.com/GrygrFlzr/kit-docs)
- [📦 Svelte Store](https://www.youtube.com/playlist?list=PLoKaNN3BjQX3fG-XOSwsPHtnV8FUY6lgK) course by lihautan covers the basics of Svelte Stores and best practices.
- [Svelte Events](https://www.youtube.com/watch?v=cbxxbBofjAw&feature=youtu.be) by WebJeda explains how directives like `on:` can be used to listen to DOM events.
- [How to Set Up Protected Routes in Your Svelte Application](https://www.webtips.dev/how-to-set-up-protected-routes-in-your-svelte-application) describes how to authenticate your users to access your routes
- [Using Fauna's streaming feature to build a chat with Svelte](https://dev.to/fauna/using-fauna-s-streaming-feature-to-build-a-chat-with-svelte-1gkd) demonstrates how to setup and configure Fauna to build a real-time chat interface with Svelte
- [Using TakeShape with Sapper](https://www.takeshape.io/articles/using-takeshape-with-sapper/) demonstrates how to connect the TakeShape CMS with Sapper
- [YastPack](https://github.com/rodabt/yastpack) is Yet Another Snowpack-Svelte-TailwindCss-Routify Template Pack
- [S2T2](https://ralphbliu.medium.com/s2t2-snowpack-svelte-tailwindcss-typescript-8928caa5af6c) is a Snowpack + Svelte + TailwindCSS + Typescript template
- [tonyketcham/sapper-tailwind2-template](https://github.com/tonyketcham/sapper-tailwind2-template) is a Sapper Template w/ Tailwind 2.0, TypeScript, ESLint, and Prettier
## See you next month!
Got something to add? Join us on [Svelte Society](https://sveltesociety.dev/), [Reddit](https://www.reddit.com/r/sveltejs/) and [Discord](https://discord.com/invite/yy75DKs)!

@ -1,67 +0,0 @@
---
title: SvelteKit is in public beta
description: And we'd love to have your feedback
author: Rich Harris
authorURL: https://twitter.com/rich_harris
---
<aside><p>Previously: <a href="/blog/whats-the-deal-with-sveltekit">What's the deal with SvelteKit?</a></p></aside>
It's time. After five months and hundreds of commits, you're finally invited to try out the SvelteKit beta. It's not finished — there are a few known bugs and several missing features — but we're really happy with how it's shaping up and can't wait for you to try it.
Starting a new project is easy:
```bash
# create the project
mkdir my-app
cd my-app
npm init svelte@next
# install dependencies
npm install
# start dev server and open a browser tab
npm run dev -- --open
```
You'll find documentation at [kit.svelte.dev/docs](https://kit.svelte.dev/docs). If you have a [Sapper](https://sapper.svelte.dev) app that you'd like to migrate to SvelteKit, you'll find instructions at [kit.svelte.dev/migrating](https://kit.svelte.dev/migrating).
The source code is available at [github.com/sveltejs/kit](https://github.com/sveltejs/kit). Issues and pull requests are disabled while we finish getting our house in order, but we'll be making it fully open in the near future.
## Wait, what is SvelteKit?
Think of it as [Next](https://nextjs.org/) for Svelte. It's a framework for building apps with Svelte, complete with server-side rendering, routing, code-splitting for JS and CSS, adapters for different serverless platforms and so on.
If you're familiar with [Sapper](https://sapper.svelte.dev), SvelteKit is Sapper's successor.
## From Snowpack to Vite
One thing that might seem surprising after the [announcement video](/blog/whats-the-deal-with-sveltekit), in which I waxed lyrical about [Snowpack](https://www.snowpack.dev/), is that SvelteKit uses [Vite](https://vitejs.dev) under the hood. When we tried Snowpack back when we started thinking about what form SvelteKit should take, it was love at first sight.
Snowpack created an entirely new category of dev tooling. Rather than _bundling_ your app in development, as we've been doing with webpack and Rollup for the last several years, Snowpack is an _unbundled dev server_ that uses the browser's native `import` and does 1:1 transformations of things like Svelte components on the fly. As a result you get quick startup, simple caching and instant hot module reloading. Once you experience this way of working, it will ruin you for anything else.
Vite falls into the same category as Snowpack. While Vite 1 wasn't suitable for SvelteKit — it was Vue-centric (Vite and Vue are both created by [Evan You](https://twitter.com/youyuxi)) and made server-side rendering difficult — Vite 2 is framework-agnostic and designed with SSR at the core. It also has powerful features, like CSS code-splitting, that we previously had to implement ourselves. When we evaluated the two technologies side-by-side we were forced to conclude that Vite is a closer match for SvelteKit's requirements and would give us the best chance to deliver the framework of our imaginations.
We owe a deep debt of gratitude to the Snowpack team, both for the close collaboration earlier in development and for lighting the path that web development will take over the next few years. It's a wonderful tool, and you should absolutely try it out.
## Dogfooding as extreme sport
SvelteKit is very much in beta, but that doesn't mean it hasn't been used in production.
My day job is at the New York Times, where I've spent much of the last twelve months working on our [coronavirus tracker](https://www.nytimes.com/interactive/2020/us/coronavirus-us-cases.html). It uses a customised version of the workflow that powers the majority of graphics at the Times, which isn't designed for large multi-page projects. When we decided late last year to create pages for each of the ~3,000 counties in the US, we quickly realised we would need to completely rearchitect the project.
Even though it was far from ready, SvelteKit was the only framework that matched our esoteric requirements. (Anyone who has worked in a newsroom and done battle with their CMS will know what I'm talking about.) Today it powers our [county risk pages](https://www.nytimes.com/interactive/2021/us/tom-green-texas-covid-cases.html) and we're in the process of migrating existing pages to the SvelteKit app.
<aside><p>I am eternally grateful for my coworkers' forbearance.</p></aside>
Using unfinished software to build an app that will be seen by millions of people is a risk, and in general I don't recommend it. But it has enabled us to develop the app much faster, and has made the framework itself much stronger than it otherwise would be.
## The road to 1.0
You can see the list of outstanding issues with the 1.0 milestone on our [issue tracker](https://github.com/sveltejs/kit/issues?q=is%3Aopen+is%3Aissue+milestone%3A1.0). Alongside that work, we plan to upgrade the documentation and add more [adapters](https://kit.svelte.dev/docs#adapters).
Most importantly though, we need your feedback to help us make the best possible app framework. Try it out, and let us know which pieces are missing.
Many thanks to everyone who has tried SvelteKit out despite the 'here be dragons' warnings and lack of documentation; your back-channel feedback has been invaluable. In particular, I want to acknowledge the work of [GrygrFlzr](https://github.com/GrygrFlzr), who maintained unofficial docs and a fork that added Windows support when we lacked it; and [dominikg](https://github.com/dominikg) whose work on [Svite](https://github.com/svitejs/svite) laid essential groundwork for SvelteKit's Vite integration. Both have now been welcomed onto the team.

@ -1,73 +0,0 @@
---
title: What's new in Svelte: April 2021
description: SvelteKit beta and new way to use slots
author: Daniel Sandoval
authorURL: https://desandoval.net
---
Two projects that have been months (even years) in the making have made their way out into the world. SvelteKit is now in public beta and slotted components are now available in Svelte!
## What's up with SvelteKit?
[SvelteKit](https://kit.svelte.dev/) - Svelte's versatile framework for building SSR, serverless applications, or SPAs - is now officially in public beta. Expect bugs! Lots more detail in the [latest blog post](https://svelte.dev/blog/sveltekit-beta). Want to know when 1.0 is close? Check out the milestone on [github](https://github.com/sveltejs/kit/milestone/2).
Want to learn more about how to get started, what's different compared to Sapper, new features and migration paths? Check out this week's [episode of Svelte Radio](https://www.svelteradio.com/episodes/svelte-kit-public-beta) for a deep dive with Antony, Kev and Swyx.
## New in Svelte & Language Tools
- Slotted components, including `<svelte:fragment slot="...">` lets component consumers target specific slots with rich content (**Svelte 3.35.0, Language Tools [104.5.0](https://github.com/sveltejs/language-tools/releases/tag/extensions-104.5.0)**, check out the [docs](https://svelte.dev/docs#svelte_fragment) and the [tutorial](https://svelte.dev/tutorial/svelte-fragment))
- Linked editing now works for HTML in Svelte files (**Language Tools, [104.6.0](https://github.com/sveltejs/language-tools/releases/tag/extensions-104.6.0)**)
- Type definitions `svelte.d.ts` are now resolved in order, allowing library authors to ship type definitions with their svelte components (**Language Tools, [104.7.0](https://github.com/sveltejs/language-tools/releases/tag/extensions-104.7.0)**)
- [vite-plugin-svelte](https://github.com/sveltejs/vite-plugin-svelte) is available for general use of Svelte in Vite. `npm init @vitejs/app` includes Svelte options using this plugin.
---
## Community Showcase
**Apps & Sites**
- [Nagato](https://nagato.app/) is a task management tool that connects popular time tracking and to-do tools all in one place.
- [type-kana](https://type-kana.cass.moe/setup) is a quiz app to help you learn ひらがな (hiragana) and カタカナ (katakana), the Japanese syllabaries.
- [Pittsburgh Steps](https://pittsburgh-steps.samlearner.com/) is an interactive map of the more than 800 sets of public outdoor stairways in Pittsburgh, PA.
- [Music Mode Wheels](https://tobx.github.io/music-mode-wheels/) is a website that displays music modes as interactive wheels.
- [Critical Notes](https://www.critical-notes.com/) helps game masters and players keep track of their roleplaying games campaigns and adventures.
- [Svelte Game of Life](https://github.com/alanrsoares/svelte-game-of-life) is an educational implementation of Conway's Game of Life in TypeScript + Svelte
- [foxql](https://github.com/foxql) is a peer to peer full text search engine that runs on your browser.
**Demos, Libraries, Tools & Components**
- [svelte-nodegui](https://github.com/nodegui/svelte-nodegui) is a way to build performant, native and cross-platform desktop applications with Node.js and Svelte
- [Svelte Story Format](https://www.npmjs.com/package/@storybook/addon-svelte-csf) allows you to write your "stories" in Storybook using the Svelte syntax. More info in the [Storybook blog](https://storybook.js.org/blog/storybook-for-svelte/)
- [SelectMadu](https://github.com/pavish/select-madu) is a replacement for the select menu, with support for searching, multiple selections, async data loading and more.
- [Svelte Checklist](https://www.npmjs.com/package/svelte-checklist) is a customizable CheckList built with Svelte.
- [Suspense for Svelte](https://www.npmjs.com/package/@jamcart/suspense) is a Svelte component that implements the core idea of React's `<Suspense>`.
- [MiniRx](https://spierala.github.io/mini-rx-store/) is a RxJS Redux Store that works with Svelte and TypeScript
- [svelte-formly](https://github.com/arabdevelop/svelte-formly) generates dynamic forms for Svelte and Sapper
- [7ty](https://www.npmjs.com/package/@jamcart/7ty) is a static site generator that uses Svelte, supports partial hydration of components, and uses file based routing resembling Sapper and 11ty.
**Want to contribute your own component?** Submit a [Component](https://sveltesociety.dev/components) to the Svelte Society site by making [a PR to this file](https://github.com/svelte-society/sveltesociety.dev/blob/master/src/pages/components/components.json).
**Starters**
- [sveltekit-electron](https://github.com/FractalHQ/sveltekit-electron) is a starter kit for Electron using SvelteKit
- [sveltekit-tailwindcss-external-api](https://github.com/acidlake/sveltekit-tailwindcss-external-api) is everything you need to build a Svelte project with TailwindCSS and an external API, powered by create-svelte.
- [Sapper Netlify](https://www.npmjs.com/package/sapper-netlify) is a Sapper project that can run on a Netlify function.
**Looking for a particular starter?** Check out [svelte-adders](https://github.com/svelte-add/svelte-adders) and a number of other integration examples at [sveltejs/integrations](https://github.com/sveltejs/integrations)
**Learning Resources**
- [How to Build a Website with Svelte and SvelteKit](https://prismic.io/blog/svelte-sveltekit-tutorial) is a step-by-step tutorial walking through the new SvelteKit setup.
- [A Svelte store for prefers-reduced-motion](https://geoffrich.net/posts/svelte-prefers-reduced-motion-store/) demonstrates how to make a custom Svelte store whose value will indicate whether the user has requested reduced motion and improve accessibility.
- [TypeScript support in Svelte](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_TypeScript) is an MDN guide to using TypeScript in Svelte.
- [How to merge cells with svelte-window](https://gradientdescent.de/merging-cells/) is a walkthrough of svelte-window, a port of the popular react-window tool for merging table cells. For more on this migration, see [from react-window 1:1 to svelte-window](https://gradientdescent.de/porting-react-window/).
- [Easy-to-Embed Svelte Components](https://codeandlife.com/2021/03/06/easy-to-embed-svelte-components/) explains how to use Rollup and a script tag to embed Svelte components anywhere.
- [Convert Svelte project from Rollup to Snowpack](https://www.youtube.com/watch?v=-sHcqj4YLeQ) walks through a common migration pattern on video.
- [How to internationalize routing in Svelte & Sapper](https://www.leaf.cloud/blog/how-to-internationalize-routing-in-svelte-sapper?utm_medium=story&utm_source=reddit.com&utm_campaign=awareness&utm_content=sapper_routing) explains how leaf.cloud translated their site to Dutch.
- [Svelte Store: Reactive context using Svelte Store](https://www.youtube.com/watch?v=-rTnWlbdjoY) is a video answer to the question, "How do we make [a] context value reactive?"
- [Creating Social Sharing Images with Cloudinary and Svelte](https://www.youtube.com/watch?v=-Si5o-R7KHY) is a video from Cloudinary that demonstrates how to dynamically develop Open Graph images and Twitter Cards for a JAMstack website.
## See you next month!
Got something to add? Join us on [Svelte Society](https://sveltesociety.dev/), [Reddit](https://www.reddit.com/r/sveltejs/) and [Discord](https://discord.com/invite/yy75DKs)!

@ -4,8 +4,8 @@ title: Before we begin
This page contains detailed API reference documentation. It's intended to be a resource for people who already have some familiarity with Svelte.
If that's not you (yet), you may prefer to visit the [interactive tutorial](tutorial) or the [examples](examples) before consulting this reference.
If that's not you (yet), you may prefer to visit the [interactive tutorial](/tutorial) or the [examples](/examples) before consulting this reference.
Don't be shy about asking for help in the [Discord chatroom](chat).
Don't be shy about asking for help in the [Discord chatroom](https://svelte.dev/chat).
Using an older version of Svelte? Have a look at the [v2 docs](https://v2.svelte.dev).

@ -0,0 +1,23 @@
---
title: Getting started
---
---
To try Svelte in an interactive online environment you can try [the REPL](https://svelte.dev/repl) or [StackBlitz](https://node.new/svelte).
To create a project locally we recommend using [SvelteKit](https://kit.svelte.dev/), the official application framework from the Svelte team:
```
npm create svelte@latest myapp
cd myapp
npm install
npm run dev
```
SvelteKit will handle calling [the Svelte compiler](https://www.npmjs.com/package/svelte) to convert your `.svelte` files into `.js` files that create the DOM and `.css` files that style it. It also provides all the other pieces you need to build a web application such as a development server, routing, and deployment. [SvelteKit](https://kit.svelte.dev/) utilizes [Vite](https://vitejs.dev/) to build your code and handle server-side rendering (SSR). There are [plugins for all the major web bundlers](https://sveltesociety.dev/tools#bundling) to handle Svelte compilation, which will output `.js` and `.css` that you can insert into your HTML, but most others won't handle SSR.
If you don't need a full-fledged app framework and instead want to build a simple frontend-only site/app, you can also use Svelte (without Kit) with Vite by running `npm init vite` and selecting the `svelte` option. With this, `npm run build` will generate HTML, JS and CSS files inside the `dist` directory.
The Svelte team maintains a [VS Code extension](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode) and there are integrations with various other [editors](https://sveltesociety.dev/tools#editor-support) and tools as well.
If you're having trouble, get help on [Discord](https://svelte.dev/chat) or [StackOverflow](https://stackoverflow.com/questions/tagged/svelte).

@ -13,22 +13,22 @@ All three sections — script, styles and markup — are optional.
// logic goes here
</script>
<!-- markup (zero or more items) goes here -->
<style>
/* styles go here */
</style>
<!-- markup (zero or more items) goes here -->
```
### &lt;script&gt;
A `<script>` block contains JavaScript that runs when a component instance is created. Variables declared (or imported) at the top level are 'visible' from the component's markup. There are four additional rules:
##### 1. `export` creates a component prop
#### 1. `export` creates a component prop
---
Svelte uses the `export` keyword to mark a variable declaration as a *property* or *prop*, which means it becomes accessible to consumers of the component (see the section on [attributes and props](docs#Attributes_and_props) for more information).
Svelte uses the `export` keyword to mark a variable declaration as a *property* or *prop*, which means it becomes accessible to consumers of the component (see the section on [attributes and props](/docs#template-syntax-attributes-and-props) for more information).
```sv
<script>
@ -44,7 +44,7 @@ Svelte uses the `export` keyword to mark a variable declaration as a *property*
You can specify a default initial value for a prop. It will be used if the component's consumer doesn't specify the prop on the component (or if its initial value is `undefined`) when instantiating the component. Note that whenever a prop is removed by the consumer, its value is set to `undefined` rather than the initial value.
In development mode (see the [compiler options](docs#svelte_compile)), a warning will be printed if no default initial value is provided and the consumer does not specify a value. To squelch this warning, ensure that a default initial value is specified, even if it is `undefined`.
In development mode (see the [compiler options](/docs#compile-time-svelte-compile)), a warning will be printed if no default initial value is provided and the consumer does not specify a value. To squelch this warning, ensure that a default initial value is specified, even if it is `undefined`.
```sv
<script>
@ -55,7 +55,7 @@ In development mode (see the [compiler options](docs#svelte_compile)), a warning
---
If you export a `const`, `class` or `function`, it is readonly from outside the component. Function *expressions* are valid props, however.
If you export a `const`, `class` or `function`, it is readonly from outside the component. Functions are valid prop values, however, as shown below.
```sv
<script>
@ -71,6 +71,8 @@ If you export a `const`, `class` or `function`, it is readonly from outside the
</script>
```
Readonly props can be accessed as properties on the element, tied to the component using [`bind:this` syntax](/docs#template-syntax-component-directives-bind-this).
---
You can use reserved words as prop names.
@ -85,7 +87,7 @@ You can use reserved words as prop names.
</script>
```
##### 2. Assignments are 'reactive'
#### 2. Assignments are 'reactive'
---
@ -93,8 +95,6 @@ To change component state and trigger a re-render, just assign to a locally decl
Update expressions (`count += 1`) and property assignments (`obj.x = y`) have the same effect.
Because Svelte's reactivity is based on assignments, using array methods like `.push()` and `.splice()` won't automatically trigger updates. Options for getting around this can be found in the [tutorial](tutorial/updating-arrays-and-objects).
```sv
<script>
let count = 0;
@ -107,15 +107,47 @@ Because Svelte's reactivity is based on assignments, using array methods like `.
</script>
```
##### 3. `$:` marks a statement as reactive
---
Because Svelte's reactivity is based on assignments, using array methods like `.push()` and `.splice()` won't automatically trigger updates. A subsequent assignment is required to trigger the update. This and more details can also be found in the [tutorial](/tutorial/updating-arrays-and-objects).
```sv
<script>
let arr = [0, 1];
function handleClick () {
// this method call does not trigger an update
arr.push(2);
// this assignment will trigger an update
// if the markup references `arr`
arr = arr
}
</script>
```
---
Any top-level statement (i.e. not inside a block or a function) can be made reactive by prefixing it with the `$:` [JS label syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/label). Reactive statements run immediately before the component updates, whenever the values that they depend on have changed.
Svelte's `<script>` blocks are run only when the component is created, so assignments within a `<script>` block are not automatically run again when a prop updates. If you'd like to track changes to a prop, see the next example in the following section.
```sv
<script>
export let person;
// this will only set `name` on component creation
// it will not update when `person` does
let { name } = person;
</script>
```
#### 3. `$:` marks a statement as reactive
---
Any top-level statement (i.e. not inside a block or a function) can be made reactive by prefixing it with the `$:` [JS label syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/label). Reactive statements run after other script code and before the component markup is rendered, whenever the values that they depend on have changed.
```sv
<script>
export let title;
export let person;
// this will update `document.title` whenever
// the `title` prop changes
@ -125,6 +157,12 @@ Any top-level statement (i.e. not inside a block or a function) can be made reac
console.log(`multiple statements can be combined`);
console.log(`the current title is ${title}`);
}
// this will update `name` when 'person' changes
$: ({ name } = person);
// don't do this. it will run before the previous line
let name2 = name;
</script>
```
@ -154,6 +192,25 @@ Total: {total}
</button>
```
---
It is important to note that the reactive blocks are ordered via simple static analysis at compile time, and all the compiler looks at are the variables that are assigned to and used within the block itself, not in any functions called by them. This means that `yDependent` will not be updated when `x` is updated in the following example:
```sv
<script>
let x = 0;
let y = 0;
const setY = (value) => {
y = value;
}
$: yDependent = y;
$: setY(x);
</script>
```
Moving the line `$: yDependent = y` below `$: setY(x)` will cause `yDependent` to be updated when `x` is updated.
---
If a statement consists entirely of an assignment to an undeclared variable, Svelte will inject a `let` declaration on your behalf.
@ -169,13 +226,13 @@ If a statement consists entirely of an assignment to an undeclared variable, Sve
</script>
```
##### 4. Prefix stores with `$` to access their values
#### 4. Prefix stores with `$` to access their values
---
A *store* is an object that allows reactive access to a value via a simple *store contract*. The [`svelte/store` module](docs#svelte_store) contains minimal store implementations which fulfil this contract.
A *store* is an object that allows reactive access to a value via a simple *store contract*. The [`svelte/store` module](/docs#run-time-svelte-store) contains minimal store implementations which fulfil this contract.
Any time you have a reference to a store, you can access its value inside a component by prefixing it with the `$` character. This causes Svelte to declare the prefixed variable, and set up a store subscription that will be unsubscribed when appropriate.
Any time you have a reference to a store, you can access its value inside a component by prefixing it with the `$` character. This causes Svelte to declare the prefixed variable, subscribe to the store at component initialization and unsubscribe when appropriate.
Assignments to `$`-prefixed variables require that the variable be a writable store, and will result in a call to the store's `.set` method.
@ -204,7 +261,7 @@ Local variables (that do not represent store values) must *not* have a `$` prefi
store = { subscribe: (subscription: (value: any) => void) => (() => void), set?: (value: any) => void }
```
You can create your own stores without relying on [`svelte/store`](docs#svelte_store), by implementing the *store contract*:
You can create your own stores without relying on [`svelte/store`](/docs#run-time-svelte-store), by implementing the *store contract*:
1. A store must contain a `.subscribe` method, which must accept as its argument a subscription function. This subscription function must be immediately and synchronously called with the store's current value upon calling `.subscribe`. All of a store's active subscription functions must later be synchronously called whenever the store's value changes.
2. The `.subscribe` method must return an unsubscribe function. Calling an unsubscribe function must stop its subscription, and its corresponding subscription function must not be called again by the store.
@ -223,7 +280,7 @@ You can `export` bindings from this block, and they will become exports of the c
You cannot `export default`, since the default export is the component itself.
> Variables defined in `module` scripts are not reactive — reassigning them will not trigger a rerender even though the variable itself will update. For values shared between multiple components, consider using a [store](docs#svelte_store).
> Variables defined in `module` scripts are not reactive — reassigning them will not trigger a rerender even though the variable itself will update. For values shared between multiple components, consider using a [store](/docs#run-time-svelte-store).
```sv
<script context="module">
@ -277,6 +334,15 @@ To apply styles to a selector globally, use the `:global(...)` modifier.
to this component */
color: goldenrod;
}
p:global(.red) {
/* this will apply to all <p> elements belonging to this
component with a class of red, even if class="red" does
not initially appear in the markup, and is instead
added at runtime. This is useful when the class
of the element is dynamically applied, for instance
when updating the element's classList property directly. */
}
</style>
```
@ -291,3 +357,23 @@ The `-global-` part will be removed when compiled, and the keyframe then be refe
@keyframes -global-my-animation-name {...}
</style>
```
---
There should only be 1 top-level `<style>` tag per component.
However, it is possible to have `<style>` tag nested inside other elements or logic blocks.
In that case, the `<style>` tag will be inserted as-is into the DOM, no scoping or processing will be done on the `<style>` tag.
```html
<div>
<style>
/* this style tag will be inserted as-is */
div {
/* this will apply to all `<div>` elements in the DOM */
color: red;
}
</style>
</div>
```

@ -124,6 +124,10 @@ An element or component can have multiple spread attributes, interspersed with r
> The `value` attribute of an `input` element or its children `option` elements must not be set with spread attributes when using `bind:group` or `bind:checked`. Svelte needs to be able to see the element's `value` directly in the markup in these cases so that it can link it to the bound variable.
> Sometimes, the attribute order matters as Svelte sets attributes sequentially in JavaScript. For example, `<input type="range" min="0" max="1" value={0.5} step="0.1"/>`, Svelte will attempt to set the value to `1` (rounding up from 0.5 as the step by default is 1), and then set the step to `0.1`. To fix this, change it to `<input type="range" min="0" max="1" step="0.1" value={0.5}/>`.
> Another example is `<img src="..." loading="lazy" />`. Svelte will set the img `src` before making the img element `loading="lazy"`, which is probably too late. Change this to `<img loading="lazy" src="...">` to make the image lazily loaded.
---
### Text expressions
@ -136,11 +140,14 @@ An element or component can have multiple spread attributes, interspersed with r
Text can also contain JavaScript expressions:
> If you're using a regular expression (`RegExp`) [literal notation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#literal_notation_and_constructor), you'll need to wrap it in parentheses.
```sv
<h1>Hello {name}!</h1>
<p>{a} + {b} = {a + b}.</p>
```
<div>{(/^[A-Za-z ]+$/).test(value) ? x : y}</div>
```
### Comments
@ -155,7 +162,7 @@ You can use HTML comments inside components.
---
Comments beginning with `svelte-ignore` disable warnings for the next block of markup. Usually these are accessibility warnings; make sure that you're disabling them for a good reason.
Comments beginning with `svelte-ignore` disable warnings for the next block of markup. Usually, these are accessibility warnings; make sure that you're disabling them for a good reason.
```sv
<!-- svelte-ignore a11y-autofocus -->
@ -199,6 +206,7 @@ Additional conditions can be added with `{:else if expression}`, optionally endi
{/if}
```
(Blocks don't have to wrap elements, they can also wrap text within elements!)
### {#each ...}
@ -306,7 +314,7 @@ An each block can also have an `{:else}` clause, which is rendered if the list i
---
Await blocks allow you to branch on the three possible states of a Promise — pending, fulfilled or rejected.
Await blocks allow you to branch on the three possible states of a Promise — pending, fulfilled or rejected. In SSR mode, only the pending state will be rendered on the server.
```sv
{#await promise}
@ -347,7 +355,7 @@ If you don't care about the pending state, you can also omit the initial block.
---
If conversely you only want to show the error state, you can omit the `then` block.
Similarly, if you only want to show the error state, you can omit the `then` block.
```sv
{#await promise catch error}
@ -393,7 +401,7 @@ When used around components, this will cause them to be reinstantiated and reini
In a text expression, characters like `<` and `>` are escaped; however, with HTML expressions, they're not.
The expression should be valid standalone HTML — `{@html "<div>"}content{@html "</div>"}` will *not* work, because `</div>` is not valid HTML.
The expression should be valid standalone HTML — `{@html "<div>"}content{@html "</div>"}` will *not* work, because `</div>` is not valid HTML. It also will *not* compile Svelte code.
> Svelte does not sanitize expressions before injecting HTML. If the data comes from an untrusted source, you must sanitize it, or you are exposing your users to an XSS vulnerability.
@ -450,13 +458,36 @@ The `{@debug ...}` tag offers an alternative to `console.log(...)`. It logs the
The `{@debug}` tag without any arguments will insert a `debugger` statement that gets triggered when *any* state changes, as opposed to the specified variables.
### {@const ...}
```sv
{@const assignment}
```
---
The `{@const ...}` tag defines a local constant.
```sv
<script>
export let boxes;
</script>
{#each boxes as box}
{@const area = box.width * box.height}
{box.width} * {box.height} = {area}
{/each}
```
`{@const}` is only allowed as direct child of `{#if}`, `{:else if}`, `{:else}`, `{#each}`, `{:then}`, `{:catch}`, `<Component />` or `<svelte:fragment />`.
### Element directives
As well as attributes, elements can have *directives*, which control the element's behaviour in some way.
#### [on:*eventname*](on_element_event)
#### on:*eventname*
```sv
on:eventname={handler}
@ -508,11 +539,13 @@ The following modifiers are available:
* `preventDefault` — calls `event.preventDefault()` before running the handler
* `stopPropagation` — calls `event.stopPropagation()`, preventing the event reaching the next element
* `stopImmediatePropagation` - calls `event.stopImmediatePropagation()`, preventing other listeners of the same event from being fired.
* `passive` — improves scrolling performance on touch/wheel events (Svelte will add it automatically where it's safe to do so)
* `nonpassive` — explicitly set `passive: false`
* `capture` — fires the handler during the *capture* phase instead of the *bubbling* phase
* `once` — remove the handler after the first time it runs
* `self` — only trigger handler if event.target is the element itself
* `self` — only trigger handler if `event.target` is the element itself
* `trusted` — only trigger handler if `event.isTrusted` is `true`. I.e. if the event is triggered by a user action.
Modifiers can be chained together, e.g. `on:click|once|capture={...}`.
@ -545,7 +578,7 @@ It's possible to have multiple event listeners for the same event:
<button on:click={increment} on:click={track}>Click me!</button>
```
#### [bind:*property*](bind_element_property)
#### bind:*property*
```sv
bind:property={variable}
@ -566,7 +599,7 @@ The simplest bindings reflect the value of a property, such as `input.value`.
---
If the name matches the value, you can use a shorthand.
If the name matches the value, you can use shorthand.
```sv
<!-- These are equivalent -->
@ -585,7 +618,7 @@ Numeric input values are coerced; even though `input.value` is a string as far a
---
On `<input>` elements with `type="file"`, you can use `bind:files` to get the [`FileList` of selected files](https://developer.mozilla.org/en-US/docs/Web/API/FileList).
On `<input>` elements with `type="file"`, you can use `bind:files` to get the [`FileList` of selected files](https://developer.mozilla.org/en-US/docs/Web/API/FileList). It is readonly.
```sv
<label for="avatar">Upload a picture:</label>
@ -598,6 +631,23 @@ On `<input>` elements with `type="file"`, you can use `bind:files` to get the [`
/>
```
---
If you're using `bind:` directives together with `on:` directives, the order that they're defined in affects the value of the bound variable when the event handler is called.
```sv
<script>
let value = 'Hello World';
</script>
<input
on:input="{() => console.log('Old value:', value)}"
bind:value
on:input="{() => console.log('New value:', value)}"
/>
```
Here we were binding to the value of a text input, which uses the `input` event. Bindings on other elements may use different events such as `change`.
##### Binding `<select>` value
@ -615,7 +665,7 @@ A `<select>` value binding corresponds to the `value` property on the selected `
---
A `<select multiple>` element behaves similarly to a checkbox group.
A `<select multiple>` element behaves similarly to a checkbox group. The bound variable is an array with an entry corresponding to the `value` property of each selected `<option>`.
```sv
<select multiple bind:value={fillings}>
@ -652,11 +702,24 @@ There are slight differences between each of these, read more about them [here](
<div contenteditable="true" bind:innerHTML={html}></div>
```
---
`<details>` elements support binding to the `open` property.
```sv
<details bind:open={isOpen}>
<summary>Details</summary>
<p>
Something small enough to escape casual notice.
</p>
</details>
```
##### Media element bindings
---
Media elements (`<audio>` and `<video>`) have their own set of bindings — six *readonly* ones...
Media elements (`<audio>` and `<video>`) have their own set of bindings — seven *readonly* ones...
* `duration` (readonly) — the total duration of the video, in seconds
* `buffered` (readonly) — an array of `{start, end}` objects
@ -664,6 +727,7 @@ Media elements (`<audio>` and `<video>`) have their own set of bindings — six
* `seekable` (readonly) — ditto
* `seeking` (readonly) — boolean
* `ended` (readonly) — boolean
* `readyState` (readonly) — number between (and including) 0 and 4
...and five *two-way* bindings:
@ -671,7 +735,7 @@ Media elements (`<audio>` and `<video>`) have their own set of bindings — six
* `playbackRate` — how fast or slow to play the video, where 1 is 'normal'
* `paused` — this one should be self-explanatory
* `volume` — a value between 0 and 1
* `muted` — a boolean value where `true` is muted
* `muted` — a boolean value indicating whether the player is muted
Videos additionally have readonly `videoWidth` and `videoHeight` bindings.
@ -684,6 +748,7 @@ Videos additionally have readonly `videoWidth` and `videoHeight` bindings.
bind:seekable
bind:seeking
bind:ended
bind:readyState
bind:currentTime
bind:playbackRate
bind:paused
@ -694,11 +759,27 @@ Videos additionally have readonly `videoWidth` and `videoHeight` bindings.
></video>
```
##### Image element bindings
---
Image elements (`<img>`) have two readonly bindings:
* `naturalWidth` (readonly) — the original width of the image, available after the image has loaded
* `naturalHeight` (readonly) — the original height of the image, available after the image has loaded
```sv
<img
bind:naturalWidth
bind:naturalHeight
></img>
```
##### Block-level element bindings
---
Block-level elements have 4 readonly bindings, measured using a technique similar to [this one](http://www.backalleycoder.com/2013/03/18/cross-browser-event-based-element-resize-detection/):
Block-level elements have 4 read-only bindings, measured using a technique similar to [this one](http://www.backalleycoder.com/2013/03/18/cross-browser-event-based-element-resize-detection/):
* `clientWidth`
* `clientHeight`
@ -742,7 +823,7 @@ Inputs that work together can use `bind:group`.
<input type="checkbox" bind:group={fillings} value="Guac (extra)">
```
#### [bind:this](bind_element)
#### bind:this
```sv
bind:this={dom_node}
@ -793,6 +874,49 @@ A `class:` directive provides a shorter way of toggling a class on an element.
<div class:active class:inactive={!active} class:isAdmin>...</div>
```
#### style:*property*
```sv
style:property={value}
```
```sv
style:property="value"
```
```sv
style:property
```
---
The `style:` directive provides a shorthand for setting multiple styles on an element.
```sv
<!-- These are equivalent -->
<div style:color="red">...</div>
<div style="color: red;">...</div>
<!-- Variables can be used -->
<div style:color={myColor}>...</div>
<!-- Shorthand, for when property and variable name match -->
<div style:color>...</div>
<!-- Multiple styles can be included -->
<div style:color style:width="12rem" style:background-color={darkMode ? "black" : "white"}>...</div>
<!-- Styles can be marked as important -->
<div style:color|important="red">...</div>
```
---
When `style:` directives are combined with `style` attributes, the directives will take precedence:
```sv
<div style="color: blue;" style:color="red">This will be red</div>
```
#### use:*action*
@ -876,7 +1000,7 @@ transition:fn|local={params}
```js
transition = (node: HTMLElement, params: any) => {
transition = (node: HTMLElement, params: any, options: { direction: 'in' | 'out' | 'both' }) => {
delay?: number,
duration?: number,
easing?: (t: number) => number,
@ -889,7 +1013,7 @@ transition = (node: HTMLElement, params: any) => {
A transition is triggered by an element entering or leaving the DOM as a result of a state change.
When a block is transitioning out, all elements inside the block, including those that do not have their own transitions, are kept in the DOM until every transition in the block has completed.
When a block is transitioning out, all elements inside the block, including those that do not have their own transitions, are kept in the DOM until every transition in the block has been completed.
The `transition:` directive indicates a *bidirectional* transition, which means it can be smoothly reversed while the transition is in progress.
@ -901,7 +1025,7 @@ The `transition:` directive indicates a *bidirectional* transition, which means
{/if}
```
> By default intro transitions will not play on first render. You can modify this behaviour by setting `intro: true` when you [create a component](docs#Client-side_component_API).
> By default intro transitions will not play on first render. You can modify this behaviour by setting `intro: true` when you [create a component](/docs#run-time-client-side-component-api).
##### Transition parameters
@ -914,7 +1038,7 @@ Like actions, transitions can have parameters.
```sv
{#if visible}
<div transition:fade="{{ duration: 2000 }}">
flies in, fades out over two seconds
fades in and out over two seconds
</div>
{/if}
```
@ -925,7 +1049,7 @@ Like actions, transitions can have parameters.
Transitions can use custom functions. If the returned object has a `css` function, Svelte will create a CSS animation that plays on the element.
The `t` argument passed to `css` is a value between `0` and `1` after the `easing` function has been applied. *In* transitions run from `0` to `1`, *out* transitions run from `1` to `0` in other words `1` is the element's natural state, as though no transition had been applied. The `u` argument is equal to `1 - t`.
The `t` argument passed to `css` is a value between `0` and `1` after the `easing` function has been applied. *In* transitions run from `0` to `1`, *out* transitions run from `1` to `0` in other words, `1` is the element's natural state, as though no transition had been applied. The `u` argument is equal to `1 - t`.
The function is called repeatedly *before* the transition begins, with different `t` and `u` arguments.
@ -964,20 +1088,22 @@ A custom transition function can also return a `tick` function, which is called
<script>
export let visible = false;
function typewriter(node, { speed = 50 }) {
function typewriter(node, { speed = 1 }) {
const valid = (
node.childNodes.length === 1 &&
node.childNodes[0].nodeType === Node.TEXT_NODE
);
if (!valid) return {};
if (!valid) {
throw new Error(`This transition only works on elements with a single text node child`);
}
const text = node.textContent;
const duration = text.length * speed;
const duration = text.length / (speed * 0.01);
return {
duration,
tick: (t, u) => {
tick: t => {
const i = ~~(text.length * t);
node.textContent = text.slice(0, i);
}
@ -986,14 +1112,19 @@ A custom transition function can also return a `tick` function, which is called
</script>
{#if visible}
<p in:typewriter="{{ speed: 20 }}">
<p in:typewriter="{{ speed: 1 }}">
The quick brown fox jumps over the lazy dog
</p>
{/if}
```
If a transition returns a function instead of a transition object, the function will be called in the next microtask. This allows multiple transitions to coordinate, making [crossfade effects](tutorial/deferred-transitions) possible.
If a transition returns a function instead of a transition object, the function will be called in the next microtask. This allows multiple transitions to coordinate, making [crossfade effects](/tutorial/deferred-transitions) possible.
Transition functions also receive a third argument, `options`, which contains information about the transition.
Available values in the `options` object are:
* `direction` - one of `in`, `out`, or `both` depending on the type of transition
##### Transition events
@ -1118,9 +1249,9 @@ DOMRect {
---
An animation is triggered when the contents of a [keyed each block](docs#each) are re-ordered. Animations do not run when an element is removed, only when the each block's data is reordered. Animate directives must be on an element that is an *immediate* child of a keyed each block.
An animation is triggered when the contents of a [keyed each block](/docs#template-syntax-each) are re-ordered. Animations do not run when an element is added or removed, only when the index of an existing data item within the each block changes. Animate directives must be on an element that is an *immediate* child of a keyed each block.
Animations can be used with Svelte's [built-in animation functions](docs#svelte_animate) or [custom animation functions](docs#Custom_animation_functions).
Animations can be used with Svelte's [built-in animation functions](/docs#run-time-svelte-animate) or [custom animation functions](/docs#template-syntax-element-directives-animate-fn-custom-animation-functions).
```sv
<!-- When `list` is reordered the animation will run-->
@ -1147,7 +1278,7 @@ As with actions and transitions, animations can have parameters.
---
Animations can use custom functions that provide the `node`, an `animation` object and any `paramaters` as arguments. The `animation` parameter is an object containing `from` and `to` properties each containing a [DOMRect](https://developer.mozilla.org/en-US/docs/Web/API/DOMRect#Properties) describing the geometry of the element in its `start` and `end` positions. The `from` property is the DOMRect of the element in its starting position, the `to` property is the DOMRect of the element in its final position after the list has been reordered and the DOM updated.
Animations can use custom functions that provide the `node`, an `animation` object and any `parameters` as arguments. The `animation` parameter is an object containing `from` and `to` properties each containing a [DOMRect](https://developer.mozilla.org/en-US/docs/Web/API/DOMRect#Properties) describing the geometry of the element in its `start` and `end` positions. The `from` property is the DOMRect of the element in its starting position, and the `to` property is the DOMRect of the element in its final position after the list has been reordered and the DOM updated.
If the returned object has a `css` method, Svelte will create a CSS animation that plays on the element.
@ -1205,9 +1336,7 @@ A custom animation function can also return a `tick` function, which is called *
duration: Math.sqrt(d) * 120,
easing: cubicOut,
tick: (t, u) =>
Object.assign(node.style, {
color: t > 0.5 ? 'Pink' : 'Blue'
});
Object.assign(node.style, { color: t > 0.5 ? 'Pink' : 'Blue' })
};
}
</script>
@ -1219,7 +1348,7 @@ A custom animation function can also return a `tick` function, which is called *
### Component directives
#### [on:*eventname*](on_component_event)
#### on:*eventname*
```sv
on:eventname={handler}
@ -1227,7 +1356,7 @@ on:eventname={handler}
---
Components can emit events using [createEventDispatcher](docs#createEventDispatcher), or by forwarding DOM events. Listening for component events looks the same as listening for DOM events:
Components can emit events using [createEventDispatcher](/docs#run-time-svelte-createeventdispatcher), or by forwarding DOM events. Listening for component events looks the same as listening for DOM events:
```sv
<SomeComponent on:whatever={handler}/>
@ -1241,8 +1370,92 @@ As with DOM events, if the `on:` directive is used without a value, the componen
<SomeComponent on:whatever/>
```
#### --style-props
```sv
--style-props="anycssvalue"
```
---
You can also pass styles as props to components for the purposes of theming, using CSS custom properties.
Svelte's implementation is essentially syntactic sugar for adding a wrapper element. This example:
```sv
<Slider
bind:value
min={0}
--rail-color="black"
--track-color="rgb(0, 0, 255)"
/>
```
---
#### [bind:*property*](bind_component_property)
Desugars to this:
```sv
<div style="display: contents; --rail-color: black; --track-color: rgb(0, 0, 255)">
<Slider
bind:value
min={0}
max={100}
/>
</div>
```
**Note**: Since this is an extra `<div>`, beware that your CSS structure might accidentally target this. Be mindful of this added wrapper element when using this feature.
---
For SVG namespace, the example above desugars into using `<g>` instead:
```sv
<g style="--rail-color: black; --track-color: rgb(0, 0, 255)">
<Slider
bind:value
min={0}
max={100}
/>
</g>
```
**Note**: Since this is an extra `<g>`, beware that your CSS structure might accidentally target this. Be mindful of this added wrapper element when using this feature.
---
Svelte's CSS Variables support allows for easily themeable components:
```sv
<!-- Slider.svelte -->
<style>
.potato-slider-rail {
background-color: var(--rail-color, var(--theme-color, 'purple'));
}
</style>
```
---
So you can set a high-level theme color:
```css
/* global.css */
html {
--theme-color: black;
}
```
---
Or override it at the consumer level:
```sv
<Slider --rail-color="goldenrod"/>
```
#### bind:*property*
```sv
bind:property={variable}
@ -1256,7 +1469,7 @@ You can bind to component props using the same syntax as for elements.
<Keypad bind:value={pin}/>
```
#### [bind:this](bind_component)
#### bind:this
```sv
bind:this={component_instance}
@ -1312,7 +1525,9 @@ The content is exposed in the child component using the `<slot>` element, which
</Widget>
```
#### [`<slot name="`*name*`">`](slot_name)
Note: If you want to render regular `<slot>` element, You can use `<svelte:element this="slot" />`.
#### `<slot name="`*name*`">`
---
@ -1355,11 +1570,11 @@ In order to place content in a slot without using a wrapper element, you can use
```
#### [`$$slots`](slots_object)
#### `$$slots`
---
`$$slots` is an object whose keys are the names of the slots passed into the component by the parent. If the parent does not pass in a slot with a particular name, that name will not be a present in `$$slots`. This allows components to render a slot (and other elements, like wrappers for styling) only if the parent provides it.
`$$slots` is an object whose keys are the names of the slots passed into the component by the parent. If the parent does not pass in a slot with a particular name, that name will not be present in `$$slots`. This allows components to render a slot (and other elements, like wrappers for styling) only if the parent provides it.
Note that explicitly passing in an empty named slot will add that slot's name to `$$slots`. For example, if a parent passes `<div slot="title" />` to a child component, `$$slots.title` will be truthy within the child.
@ -1381,11 +1596,11 @@ Note that explicitly passing in an empty named slot will add that slot's name to
</Card>
```
#### [`<slot let:`*name*`={`*value*`}>`](slot_let)
#### `<slot key={`*value*`}>`
---
Slots can be rendered zero or more times, and can pass values *back* to the parent using props. The parent exposes the values to the slot template using the `let:` directive.
Slots can be rendered zero or more times and can pass values *back* to the parent using props. The parent exposes the values to the slot template using the `let:` directive.
The usual shorthand rules apply — `let:item` is equivalent to `let:item={item}`, and `<slot {item}>` is equivalent to `<slot item={item}>`.
@ -1466,6 +1681,30 @@ If `this` is falsy, no component is rendered.
<svelte:component this={currentSelection.component} foo={bar}/>
```
### `<svelte:element>`
```sv
<svelte:element this={expression}/>
```
---
The `<svelte:element>` element lets you render an element of a dynamically specified type. This is useful for example when displaying rich text content from a CMS. Any properties and event listeners present will be applied to the element.
The only supported binding is `bind:this`, since the element type-specific bindings that Svelte does at build time (e.g. `bind:value` for input elements) do not work with a dynamic tag type.
If `this` has a nullish value, the element and its children will not be rendered.
If `this` is the name of a [void element](https://developer.mozilla.org/en-US/docs/Glossary/Void_element) (e.g., `br`) and `<svelte:element>` has child elements, a runtime error will be thrown in development mode.
```sv
<script>
let tag = 'div';
export let handler;
</script>
<svelte:element this={tag} on:click={handler}>Foo</svelte:element>
```
### `<svelte:window>`
@ -1480,6 +1719,8 @@ If `this` is falsy, no component is rendered.
The `<svelte:window>` element allows you to add event listeners to the `window` object without worrying about removing them when the component is destroyed, or checking for the existence of `window` when server-side rendering.
Unlike `<svelte:self>`, this element may only appear at the top level of your component and must never be inside a block or element.
```sv
<script>
function handleKeydown(event) {
@ -1500,7 +1741,7 @@ You can also bind to the following properties:
* `outerHeight`
* `scrollX`
* `scrollY`
* `online` — an alias for window.navigator.onLine
* `online` — an alias for `window.navigator.onLine`
All except `scrollX` and `scrollY` are readonly.
@ -1508,6 +1749,26 @@ All except `scrollX` and `scrollY` are readonly.
<svelte:window bind:scrollY={y}/>
```
> Note that the page will not be scrolled to the initial value to avoid accessibility issues. Only subsequent changes to the bound variable of `scrollX` and `scrollY` will cause scrolling. However, if the scrolling behaviour is desired, call `scrollTo()` in `onMount()`.
### `<svelte:document>`
```sv
<svelte:document on:event={handler}/>
```
---
Similarly to `<svelte:window>`, this element allows you to add listeners to events on `document`, such as `visibilitychange`, which don't fire on `window`. It also lets you use [actions](/docs#template-syntax-element-directives-use-action) on `document`.
As with `<svelte:window>`, this element may only appear the top level of your component and must never be inside a block or element.
```sv
<svelte:document
on:visibilitychange={handleVisibilityChange}
use:someAction
/>
```
### `<svelte:body>`
@ -1517,12 +1778,15 @@ All except `scrollX` and `scrollY` are readonly.
---
As with `<svelte:window>`, this element allows you to add listeners to events on `document.body`, such as `mouseenter` and `mouseleave` which don't fire on `window`.
Similarly to `<svelte:window>`, this element allows you to add listeners to events on `document.body`, such as `mouseenter` and `mouseleave`, which don't fire on `window`. It also lets you use [actions](/docs#template-syntax-element-directives-use-action) on the `<body>` element.
As with `<svelte:window>` and `<svelte:document>`, this element may only appear the top level of your component and must never be inside a block or element.
```sv
<svelte:body
on:mouseenter={handleMouseenter}
on:mouseleave={handleMouseleave}
use:someAction
/>
```
@ -1537,9 +1801,11 @@ As with `<svelte:window>`, this element allows you to add listeners to events on
This element makes it possible to insert elements into `document.head`. During server-side rendering, `head` content is exposed separately to the main `html` content.
As with `<svelte:window>`, `<svelte:document>` and `<svelte:body>`, this element may only appear at the top level of your component and must never be inside a block or element.
```sv
<svelte:head>
<link rel="stylesheet" href="tutorial/dark-theme.css">
<link rel="stylesheet" href="/tutorial/dark-theme.css">
</svelte:head>
```
@ -1552,7 +1818,7 @@ This element makes it possible to insert elements into `document.head`. During s
---
The `<svelte:options>` element provides a place to specify per-component compiler options, which are detailed in the [compiler section](docs#svelte_compile). The possible options are:
The `<svelte:options>` element provides a place to specify per-component compiler options, which are detailed in the [compiler section](/docs#compile-time-svelte-compile). The possible options are:
* `immutable={true}` — you never use mutable data, so the compiler can do simple referential equality checks to determine if values have changed
* `immutable={false}` — the default. Svelte will be more conservative about whether or not mutable objects have changed
@ -1567,7 +1833,7 @@ The `<svelte:options>` element provides a place to specify per-component compile
### `<svelte:fragment>`
The `<svelte:fragment>` element allows you to place content in a [named slot](docs#slot_name) without wrapping it in a container DOM element. This keeps the flow layout of your document intact.
The `<svelte:fragment>` element allows you to place content in a [named slot](/docs#template-syntax-slot-slot-name-name) without wrapping it in a container DOM element. This keeps the flow layout of your document intact.
```sv
<!-- Widget.svelte -->

@ -5,7 +5,7 @@ title: Run time
### `svelte`
The `svelte` package exposes [lifecycle functions](tutorial/onmount) and the [context API](tutorial/context-api).
The `svelte` package exposes [lifecycle functions](/tutorial/onmount) and the [context API](/tutorial/context-api).
#### `onMount`
@ -20,7 +20,7 @@ onMount(callback: () => () => void)
The `onMount` function schedules a callback to run as soon as the component has been mounted to the DOM. It must be called during the component's initialisation (but doesn't need to live *inside* the component; it can be called from an external module).
`onMount` does not run inside a [server-side component](docs#Server-side_component_API).
`onMount` does not run inside a [server-side component](/docs#run-time-server-side-component-api).
```sv
<script>
@ -84,6 +84,8 @@ afterUpdate(callback: () => void)
Schedules a callback to run immediately after the component has been updated.
> The first time the callback runs will be after the initial `onMount`
```sv
<script>
import { afterUpdate } from 'svelte';
@ -146,7 +148,7 @@ setContext(key: any, context: any)
---
Associates an arbitrary `context` object with the current component and the specified `key`. The context is then available to children of the component (including slotted content) with `getContext`.
Associates an arbitrary `context` object with the current component and the specified `key` and returns that object. The context is then available to children of the component (including slotted content) with `getContext`.
Like lifecycle functions, this must be called during component initialisation.
@ -198,17 +200,35 @@ Checks whether a given `key` has been set in the context of a parent component.
</script>
```
#### `getAllContexts`
```js
contexts: Map<any, any> = getAllContexts()
```
---
Retrieves the whole context map that belongs to the closest parent component. Must be called during component initialisation. Useful, for example, if you programmatically create a component and want to pass the existing context to it.
```sv
<script>
import { getAllContexts } from 'svelte';
const contexts = getAllContexts();
</script>
```
#### `createEventDispatcher`
```js
dispatch: ((name: string, detail?: any) => void) = createEventDispatcher();
dispatch: ((name: string, detail?: any, options?: DispatchOptions) => boolean) = createEventDispatcher();
```
---
Creates an event dispatcher that can be used to dispatch [component events](docs#on_component_event). Event dispatchers are functions that can take two arguments: `name` and `detail`.
Creates an event dispatcher that can be used to dispatch [component events](/docs#template-syntax-component-directives-on-eventname). Event dispatchers are functions that can take two arguments: `name` and `detail`.
Component events created with `createEventDispatcher` create a [CustomEvent](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent). These events do not [bubble](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#Event_bubbling_and_capture) and are not cancellable with `event.preventDefault()`. The `detail` argument corresponds to the [CustomEvent.detail](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail) property and can contain any type of data.
Component events created with `createEventDispatcher` create a [CustomEvent](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent). These events do not [bubble](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#Event_bubbling_and_capture). The `detail` argument corresponds to the [CustomEvent.detail](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail) property and can contain any type of data.
```sv
<script>
@ -234,21 +254,42 @@ Events dispatched from child components can be listened to in their parent. Any
<Child on:notify="{callbackFunction}"/>
```
---
Events can be cancelable by passing a third parameter to the dispatch function. The function returns `false` if the event is cancelled with `event.preventDefault()`, otherwise it returns `true`.
```sv
<script>
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
function notify() {
const shouldContinue = dispatch('notify', 'detail value', { cancelable: true });
if (shouldContinue) {
// no one called preventDefault
} else {
// a listener called preventDefault
}
}
</script>
```
### `svelte/store`
The `svelte/store` module exports functions for creating [readable](docs#readable), [writable](docs#writable) and [derived](docs#derived) stores.
The `svelte/store` module exports functions for creating [readable](/docs#run-time-svelte-store-readable), [writable](/docs#run-time-svelte-store-writable) and [derived](/docs#run-time-svelte-store-derived) stores.
Keep in mind that you don't *have* to use these functions to enjoy the [reactive `$store` syntax](docs#4_Prefix_stores_with_$_to_access_their_values) in your components. Any object that correctly implements `.subscribe`, unsubscribe, and (optionally) `.set` is a valid store, and will work both with the special syntax, and with Svelte's built-in [`derived` stores](docs#derived).
Keep in mind that you don't *have* to use these functions to enjoy the [reactive `$store` syntax](/docs#component-format-script-4-prefix-stores-with-$-to-access-their-values) in your components. Any object that correctly implements `.subscribe`, unsubscribe, and (optionally) `.set` is a valid store, and will work both with the special syntax, and with Svelte's built-in [`derived` stores](/docs#run-time-svelte-store-derived).
This makes it possible to wrap almost any other reactive state handling library for use in Svelte. Read more about the [store contract](docs#Store_contract) to see what a correct implementation looks like.
This makes it possible to wrap almost any other reactive state handling library for use in Svelte. Read more about the [store contract](/docs#component-format-script-4-prefix-stores-with-$-to-access-their-values-store-contract) to see what a correct implementation looks like.
#### `writable`
```js
store = writable(value: any)
store = writable(value?: any)
```
```js
store = writable(value: any, (set: (value: any) => void) => () => void)
store = writable(value?: any, start?: (set: (value: any) => void) => () => void)
```
---
@ -294,17 +335,17 @@ const unsubscribe = count.subscribe(value => {
unsubscribe(); // logs 'no more subscribers'
```
Note that the value of a `writable` is lost when it is destroyed, for example when the page is refreshed. However, you can write your own logic to sync the value to for example the `localStorage`.
#### `readable`
```js
store = readable(value: any, (set: (value: any) => void) => () => void)
store = readable(value?: any, start?: (set: (value: any) => void) => () => void)
```
---
Creates a store whose value cannot be set from 'outside', the first argument is the store's initial value.
The second argument to `readable` is the same as the second argument to `writable`, except that it is required with `readable` (since otherwise there would be no way to update the store value).
Creates a store whose value cannot be set from 'outside', the first argument is the store's initial value, and the second argument to `readable` is the same as the second argument to `writable`.
```js
import { readable } from 'svelte/store';
@ -337,7 +378,7 @@ store = derived([a, ...b], callback: ([a: any, ...b: any[]], set: (value: any) =
---
Derives a store from one or more other stores. Whenever those dependencies change, the callback runs.
Derives a store from one or more other stores. The callback runs initially when the first subscriber subscribes and then whenever the store dependencies change.
In the simplest version, `derived` takes a single store, and the callback returns a derived value.
@ -411,6 +452,29 @@ import { get } from 'svelte/store';
const value = get(store);
```
#### `readonly`
```js
readableStore = readonly(writableStore);
```
---
This simple helper function makes a store readonly. You can still subscribe to the changes from the original one using this new readable store.
```js
import { readonly } from 'svelte/store';
const writableStore = writable(1);
const readableStore = readonly(writableStore);
readableStore.subscribe(console.log);
writableStore.set(2); // console: 2
readableStore.set(2); // ERROR
```
### `svelte/motion`
@ -425,8 +489,8 @@ store = tweened(value: any, options)
Tweened stores update their values over a fixed duration. The following options are available:
* `delay` (`number`, default 0) — milliseconds before starting
* `duration` (`number`, default 400) — milliseconds the tween lasts
* `easing` (`function`, default `t => t`) — an [easing function](docs#svelte_easing)
* `duration` (`number` | `function`, default 400) — milliseconds the tween lasts
* `easing` (`function`, default `t => t`) — an [easing function](/docs#run-time-svelte-easing)
* `interpolate` (`function`) — see below
`store.set` and `store.update` can accept a second `options` argument that will override the options passed in upon instantiation.
@ -513,15 +577,39 @@ A `spring` store gradually changes to its target value based on its `stiffness`
* `stiffness` (`number`, default `0.15`) — a value between 0 and 1 where higher means a 'tighter' spring
* `damping` (`number`, default `0.8`) — a value between 0 and 1 where lower means a 'springier' spring
* `precision` (`number`, default `0.001`) — determines the threshold at which the spring is considered to have 'settled', where lower means more precise
* `precision` (`number`, default `0.01`) — determines the threshold at which the spring is considered to have 'settled', where lower means more precise
---
All of the options above can be changed while the spring is in motion, and will take immediate effect.
```js
const size = spring(100);
size.stiffness = 0.3;
size.damping = 0.4;
size.precision = 0.005;
```
---
As with [`tweened`](docs#tweened) stores, `set` and `update` return a Promise that resolves if the spring settles. The `store.stiffness` and `store.damping` properties can be changed while the spring is in motion, and will take immediate effect.
As with [`tweened`](/docs#run-time-svelte-motion-tweened) stores, `set` and `update` return a Promise that resolves if the spring settles.
Both `set` and `update` can take a second argument — an object with `hard` or `soft` properties. `{ hard: true }` sets the target value immediately; `{ soft: n }` preserves existing momentum for `n` seconds before settling. `{ soft: true }` is equivalent to `{ soft: 0.5 }`.
[See a full example on the spring tutorial.](tutorial/spring)
```js
const coords = spring({ x: 50, y: 50 });
// updates the value immediately
coords.set({ x: 100, y: 200 }, { hard: true });
// preserves existing momentum for 1s
coords.update(
(target_coords, coords) => {
return { x: target_coords.x, y: coords.y };
},
{ soft: 1 }
);
```
[See a full example on the spring tutorial.](/tutorial/spring)
```sv
<script>
@ -545,7 +633,7 @@ $: $size = big ? 100 : 10;
### `svelte/transition`
The `svelte/transition` module exports seven functions: `fade`, `blur`, `fly`, `slide`, `scale`, `draw` and `crossfade`. They are for use with Svelte [`transitions`](docs#transition_fn).
The `svelte/transition` module exports seven functions: `fade`, `blur`, `fly`, `slide`, `scale`, `draw` and `crossfade`. They are for use with Svelte [`transitions`](/docs#template-syntax-element-directives-transition-fn).
#### `fade`
@ -567,9 +655,9 @@ Animates the opacity of an element from 0 to the current opacity for `in` transi
* `delay` (`number`, default 0) — milliseconds before starting
* `duration` (`number`, default 400) — milliseconds the transition lasts
* `easing` (`function`, default `linear`) — an [easing function](docs#svelte_easing)
* `easing` (`function`, default `linear`) — an [easing function](/docs#run-time-svelte-easing)
You can see the `fade` transition in action in the [transition tutorial](tutorial/transition).
You can see the `fade` transition in action in the [transition tutorial](/tutorial/transition).
```sv
<script>
@ -603,9 +691,9 @@ Animates a `blur` filter alongside an element's opacity.
* `delay` (`number`, default 0) — milliseconds before starting
* `duration` (`number`, default 400) — milliseconds the transition lasts
* `easing` (`function`, default `cubicInOut`) — an [easing function](docs#svelte_easing)
* `easing` (`function`, default `cubicInOut`) — an [easing function](/docs#run-time-svelte-easing)
* `opacity` (`number`, default 0) - the opacity value to animate out to and in from
* `amount` (`number`, default 5) - the size of the blur in pixels
* `amount` (`number | string`, default 5) - the size of the blur. Supports css units (for example: `"4rem"`). The default unit is `px`
```sv
<script>
@ -633,18 +721,19 @@ out:fly={params}
---
Animates the x and y positions and the opacity of an element. `in` transitions animate from an element's current (default) values to the provided values, passed as parameters. `out` transitions animate from the provided values to an element's default values.
Animates the x and y positions and the opacity of an element. `in` transitions animate from the provided values, passed as parameters to the element's default values. `out` transitions animate from the element's default values to the provided values.
`fly` accepts the following parameters:
* `delay` (`number`, default 0) — milliseconds before starting
* `duration` (`number`, default 400) — milliseconds the transition lasts
* `easing` (`function`, default `cubicOut`) — an [easing function](docs#svelte_easing)
* `x` (`number`, default 0) - the x offset to animate out to and in from
* `y` (`number`, default 0) - the y offset to animate out to and in from
* `easing` (`function`, default `cubicOut`) — an [easing function](/docs#run-time-svelte-easing)
* `x` (`number | string`, default 0) - the x offset to animate out to and in from
* `y` (`number | string`, default 0) - the y offset to animate out to and in from
* `opacity` (`number`, default 0) - the opacity value to animate out to and in from
You can see the `fly` transition in action in the [transition tutorial](tutorial/adding-parameters-to-transitions).
x and y use `px` by default but support css units, for example `x: '100vw'` or `y: '50%'`.
You can see the `fly` transition in action in the [transition tutorial](/tutorial/adding-parameters-to-transitions).
```sv
<script>
@ -679,7 +768,8 @@ Slides an element in and out.
* `delay` (`number`, default 0) — milliseconds before starting
* `duration` (`number`, default 400) — milliseconds the transition lasts
* `easing` (`function`, default `cubicOut`) — an [easing function](docs#svelte_easing)
* `easing` (`function`, default `cubicOut`) — an [easing function](/docs#run-time-svelte-easing)
- `axis` (`x` | `y`, default `y`) — the axis of motion along which the transition occurs
```sv
<script>
@ -688,8 +778,8 @@ Slides an element in and out.
</script>
{#if condition}
<div transition:slide="{{delay: 250, duration: 300, easing: quintOut }}">
slides in and out
<div transition:slide="{{delay: 250, duration: 300, easing: quintOut, axis: 'x'}}">
slides in and out horizontally
</div>
{/if}
```
@ -714,7 +804,7 @@ Animates the opacity and scale of an element. `in` transitions animate from an e
* `delay` (`number`, default 0) — milliseconds before starting
* `duration` (`number`, default 400) — milliseconds the transition lasts
* `easing` (`function`, default `cubicOut`) — an [easing function](docs#svelte_easing)
* `easing` (`function`, default `cubicOut`) — an [easing function](/docs#run-time-svelte-easing)
* `start` (`number`, default 0) - the scale value to animate out to and in from
* `opacity` (`number`, default 0) - the opacity value to animate out to and in from
@ -752,9 +842,9 @@ Animates the stroke of an SVG element, like a snake in a tube. `in` transitions
* `delay` (`number`, default 0) — milliseconds before starting
* `speed` (`number`, default undefined) - the speed of the animation, see below.
* `duration` (`number` | `function`, default 800) — milliseconds the transition lasts
* `easing` (`function`, default `cubicInOut`) — an [easing function](docs#svelte_easing)
* `easing` (`function`, default `cubicInOut`) — an [easing function](/docs#run-time-svelte-easing)
The `speed` parameter is a means of setting the duration of the transition relative to the path's length. It is modifier that is applied to the length of the path: `duration = length / speed`. A path that is 1000 pixels with a speed of 1 will have a duration of `1000ms`, setting the speed to `0.5` will double that duration and setting it to `2` will halve it.
The `speed` parameter is a means of setting the duration of the transition relative to the path's length. It is a modifier that is applied to the length of the path: `duration = length / speed`. A path that is 1000 pixels with a speed of 1 will have a duration of `1000ms`, setting the speed to `0.5` will double that duration and setting it to `2` will halve it.
```sv
<script>
@ -777,13 +867,41 @@ The `speed` parameter is a means of setting the duration of the transition relat
```
<!-- Crossfade is coming soon... -->
#### `crossfade`
The `crossfade` function creates a pair of [transitions](/docs#template-syntax-element-directives-transition-fn) called `send` and `receive`. When an element is 'sent', it looks for a corresponding element being 'received', and generates a transition that transforms the element to its counterpart's position and fades it out. When an element is 'received', the reverse happens. If there is no counterpart, the `fallback` transition is used.
---
`crossfade` accepts the following parameters:
* `delay` (`number`, default 0) — milliseconds before starting
* `duration` (`number` | `function`, default 800) — milliseconds the transition lasts
* `easing` (`function`, default `cubicOut`) — an [easing function](/docs#run-time-svelte-easing)
* `fallback` (`function`) — A fallback [transition](/docs#template-syntax-element-directives-transition-fn) to use for send when there is no matching element being received, and for receive when there is no element being sent.
```sv
<script>
import { crossfade } from 'svelte/transition';
import { quintOut } from 'svelte/easing';
const [send, receive] = crossfade({
duration:1500,
easing: quintOut
});
</script>
{#if condition}
<h1 in:send={{key}} out:receive={{key}}>BIG ELEM</h1>
{:else}
<small in:send={{key}} out:receive={{key}}>small elem</small>
{/if}
```
### `svelte/animate`
The `svelte/animate` module exports one function for use with Svelte [animations](docs#animate_fn).
The `svelte/animate` module exports one function for use with Svelte [animations](/docs#template-syntax-element-directives-animate-fn).
#### `flip`
@ -797,17 +915,17 @@ The `flip` function calculates the start and end position of an element and anim
* `delay` (`number`, default 0) — milliseconds before starting
* `duration` (`number` | `function`, default `d => Math.sqrt(d) * 120`) — see below
* `easing` (`function`, default `cubicOut`) — an [easing function](docs#svelte_easing)
* `easing` (`function`, default `cubicOut`) — an [easing function](/docs#run-time-svelte-easing)
`duration` can be be provided as either:
`duration` can be provided as either:
- a `number`, in milliseconds.
- a function, `distance: number => duration: number`, receiving the distance the element will travel in pixels and returning the duration in milliseconds. This allows you to assign a duration that is relative to the distance travelled by each element.
---
You can see a full example on the [animations tutorial](tutorial/animate)
You can see a full example on the [animations tutorial](/tutorial/animate)
```sv
@ -831,7 +949,7 @@ You can see a full example on the [animations tutorial](tutorial/animate)
Easing functions specify the rate of change over time and are useful when working with Svelte's built-in transitions and animations as well as the tweened and spring utilities. `svelte/easing` contains 31 named exports, a `linear` ease and 3 variants of 10 different easing functions: `in`, `out` and `inOut`.
You can explore the various eases using the [ease visualiser](examples#easing) in the [examples section](examples).
You can explore the various eases using the [ease visualiser](/examples/easing) in the [examples section](/examples).
| ease | in | out | inOut |
@ -901,7 +1019,7 @@ The following initialisation options can be provided:
| option | default | description |
| --- | --- | --- |
| `target` | **none** | An `HTMLElement` to render to. This option is required
| `target` | **none** | An `HTMLElement` or `ShadowRoot` to render to. This option is required
| `anchor` | `null` | A child of `target` to render the component immediately before
| `props` | `{}` | An object of properties to supply to the component
| `context` | `new Map()` | A `Map` of root-level context key-value pairs to supply to the component
@ -913,7 +1031,7 @@ Existing children of `target` are left where they are.
---
The `hydrate` option instructs Svelte to upgrade existing DOM (usually from server-side rendering) rather than creating new elements. It will only work if the component was compiled with the [`hydratable: true` option](docs#svelte_compile). Hydration of `<head>` elements only works properly if the server-side rendering code was also compiled with `hydratable: true`, which adds a marker to each element in the `<head>` so that the component knows which elements it's responsible for removing during hydration.
The `hydrate` option instructs Svelte to upgrade existing DOM (usually from server-side rendering) rather than creating new elements. It will only work if the component was compiled with the [`hydratable: true` option](/docs#compile-time-svelte-compile). Hydration of `<head>` elements only works properly if the server-side rendering code was also compiled with `hydratable: true`, which adds a marker to each element in the `<head>` so that the component knows which elements it's responsible for removing during hydration.
Whereas children of `target` are normally left alone, `hydrate: true` will cause any children to be removed. For that reason, the `anchor` option cannot be used alongside `hydrate: true`.
@ -997,7 +1115,7 @@ app.count += 1;
---
Svelte components can also be compiled to custom elements (aka web components) using the `customElement: true` compiler option. You should specify a tag name for the component using the `<svelte:options>` [element](docs#svelte_options).
Svelte components can also be compiled to custom elements (aka web components) using the `customElement: true` compiler option. You should specify a tag name for the component using the `<svelte:options>` [element](/docs#template-syntax-svelte-options).
```sv
<svelte:options tag="my-element" />
@ -1034,7 +1152,7 @@ document.body.innerHTML = `
---
By default, custom elements are compiled with `accessors: true`, which means that any [props](docs#Attributes_and_props) are exposed as properties of the DOM element (as well as being readable/writable as attributes, where possible).
By default, custom elements are compiled with `accessors: true`, which means that any [props](/docs#template-syntax-attributes-and-props) are exposed as properties of the DOM element (as well as being readable/writable as attributes, where possible).
To prevent this, add `accessors={false}` to `<svelte:options>`.
@ -1071,7 +1189,7 @@ Unlike client-side components, server-side components don't have a lifespan afte
A server-side component exposes a `render` method that can be called with optional props. It returns an object with `head`, `html`, and `css` properties, where `head` contains the contents of any `<svelte:head>` elements encountered.
You can import a Svelte component directly into Node using [`svelte/register`](docs#svelte_register).
You can import a Svelte component directly into Node using [`svelte/register`](/docs#run-time-svelte-register).
```js
require('svelte/register');

@ -2,11 +2,7 @@
title: Compile time
---
Typically, you won't interact with the Svelte compiler directly, but will instead integrate it into your build system using a bundler plugin:
* [rollup-plugin-svelte](https://github.com/sveltejs/rollup-plugin-svelte) for users of [Rollup](https://rollupjs.org)
* [svelte-loader](https://github.com/sveltejs/svelte-loader) for users of [webpack](https://webpack.js.org)
* or one of the [community-maintained plugins](https://github.com/sveltejs/integrations#bundler-plugins)
Typically, you won't interact with the Svelte compiler directly, but will instead integrate it into your build system using a bundler plugin. The bundler plugin that the Svelte team most recommends and invests in is [vite-plugin-svelte](https://github.com/sveltejs/vite-plugin-svelte). The [SvelteKit](https://kit.svelte.dev/) framework provides a setup leveraging `vite-plugin-svelte` to build applications as well as a [tool for packaging Svelte component libraries](https://kit.svelte.dev/docs/packaging). Svelte Society maintains a list of [other bundler plugins](https://sveltesociety.dev/tools/#bundling) for additional tools like Rollup and Webpack.
Nonetheless, it's useful to understand how to use the compiler, since bundler plugins generally expose compiler options to you.
@ -44,7 +40,9 @@ The following options can be passed to the compiler. None are required:
| `filename` | string | `null`
| `name` | string | `"Component"`
| `format` | `"esm"` or `"cjs"` | `"esm"`
| `generate` | `"dom"` or `"ssr"` | `"dom"`
| `generate` | `"dom"` or `"ssr"` or `false` | `"dom"`
| `errorMode` | `"throw"` or `"warn"` | `"throw"`
| `varsReport` | `"strict"` or `"full"` or `false` | `"strict"`
| `dev` | boolean | `false`
| `immutable` | boolean | `false`
| `hydratable` | boolean | `false`
@ -66,6 +64,8 @@ The following options can be passed to the compiler. None are required:
| `name` | `"Component"` | `string` that sets the name of the resulting JavaScript class (though the compiler will rename it if it would otherwise conflict with other variables in scope). It will normally be inferred from `filename`.
| `format` | `"esm"` | If `"esm"`, creates a JavaScript module (with `import` and `export`). If `"cjs"`, creates a CommonJS module (with `require` and `module.exports`), which is useful in some server-side rendering situations or for testing.
| `generate` | `"dom"` | If `"dom"`, Svelte emits a JavaScript class for mounting to the DOM. If `"ssr"`, Svelte emits an object with a `render` method suitable for server-side rendering. If `false`, no JavaScript or CSS is returned; just metadata.
| `errorMode` | `"throw"` | If `"throw"`, Svelte throws when a compilation error occurred. If `"warn"`, Svelte will treat errors as warnings and add them to the warning report.
| `varsReport` | `"strict"` | If `"strict"`, Svelte returns a variables report with only variables that are not globals nor internals. If `"full"`, Svelte returns a variables report with all detected variables. If `false`, no variables report is returned.
| `dev` | `false` | If `true`, causes extra code to be added to components that will perform runtime checks and provide debugging information during development.
| `immutable` | `false` | If `true`, tells the compiler that you promise not to mutate any objects. This allows it to be less conservative about checking whether values have changed.
| `hydratable` | `false` | If `true` when generating DOM code, enables the `hydrate: true` runtime option, which allows a component to upgrade existing DOM rather than creating new DOM from scratch. When generating SSR code, this adds markers to `<head>` elements so that hydration knows which to replace.
@ -73,11 +73,13 @@ The following options can be passed to the compiler. None are required:
| `accessors` | `false` | If `true`, getters and setters will be created for the component's props. If `false`, they will only be created for readonly exported values (i.e. those declared with `const`, `class` and `function`). If compiling with `customElement: true` this option defaults to `true`.
| `customElement` | `false` | If `true`, tells the compiler to generate a custom element constructor instead of a regular Svelte component.
| `tag` | `null` | A `string` that tells Svelte what tag name to register the custom element with. It must be a lowercase alphanumeric string with at least one hyphen, e.g. `"my-element"`.
| `css` | `true` | If `true`, styles will be included in the JavaScript class and injected at runtime. It's recommended that you set this to `false` and use the CSS that is statically generated, as it will result in smaller JavaScript bundles and better performance.
| `css` | `'injected'` | If `'injected'` (formerly `true`), styles will be included in the JavaScript class and injected at runtime for the components actually rendered. If `'external'` (formerly `false`), the CSS will be returned in the `css` field of the compilation result. Most Svelte bundler plugins will set this to `'external'` and use the CSS that is statically generated for better performance, as it will result in smaller JavaScript bundles and the output can be served as cacheable `.css` files. If `'none'`, styles are completely avoided and no CSS output is generated.
| `cssHash` | See right | A function that takes a `{ hash, css, name, filename }` argument and returns the string that is used as a classname for scoped CSS. It defaults to returning `svelte-${hash(css)}`
| `loopGuardTimeout` | 0 | A `number` that tells Svelte to break the loop if it blocks the thread for more than `loopGuardTimeout` ms. This is useful to prevent infinite loops. **Only available when `dev: true`**
| `preserveComments` | `false` | If `true`, your HTML comments will be preserved during server-side rendering. By default, they are stripped out.
| `preserveWhitespace` | `false` | If `true`, whitespace inside and between elements is kept as you typed it, rather than removed or collapsed to a single space where possible.
| `sourcemap` | `object \| string` | An initial sourcemap that will be merged into the final output sourcemap. This is usually the preprocessor sourcemap.
| `enableSourcemap` | `boolean \| { js: boolean; css: boolean; }` | If `true`, Svelte generate sourcemaps for components. Use an object with `js` or `css` for more granular control of sourcemap generation. By default, this is `true`.
| `outputFilename` | `null` | A `string` used for your JavaScript sourcemap.
| `cssOutputFilename` | `null` | A `string` used for your CSS sourcemap.
| `sveltePath` | `"svelte"` | The location of the `svelte` package. Any imports from `svelte` or `svelte/[module]` will be modified accordingly.
@ -172,7 +174,7 @@ ast: object = svelte.parse(
---
The `parse` function parses a component, returning only its abstract syntax tree. Unlike compiling with the `generate: false` option, this will not perform any validation or other analysis of the component beyond parsing it.
The `parse` function parses a component, returning only its abstract syntax tree. Unlike compiling with the `generate: false` option, this will not perform any validation or other analysis of the component beyond parsing it. Note that the returned AST is not considered public API, so breaking changes could occur at any point in time.
```js
@ -184,7 +186,7 @@ const ast = svelte.parse(source, { filename: 'App.svelte' });
### `svelte.preprocess`
A number of [community-maintained preprocessing plugins](https://github.com/sveltejs/integrations#preprocessors) are available to allow you to use Svelte with tools like TypeScript, PostCSS, SCSS, and Less.
A number of [community-maintained preprocessing plugins](https://sveltesociety.dev/tools#preprocessors) are available to allow you to use Svelte with tools like TypeScript, PostCSS, SCSS, and Less.
You can write your own preprocessor using the `svelte.preprocess` API.
@ -224,16 +226,24 @@ Each `markup`, `script` or `style` function must return an object (or a Promise
The `markup` function receives the entire component source text, along with the component's `filename` if it was specified in the third argument.
> Preprocessor functions may additionally return a `map` object alongside `code` and `dependencies`, where `map` is a sourcemap representing the transformation. In current versions of Svelte it will be ignored, but future versions of Svelte may take account of preprocessor sourcemaps.
> Preprocessor functions should additionally return a `map` object alongside `code` and `dependencies`, where `map` is a sourcemap representing the transformation.
```js
const svelte = require('svelte/compiler');
const MagicString = require('magic-string');
const { code } = await svelte.preprocess(source, {
markup: ({ content, filename }) => {
const pos = content.indexOf('foo');
if(pos < 0) {
return { code: content }
}
const s = new MagicString(content, { filename })
s.overwrite(pos, pos + 3, 'bar', { storeName: true })
return {
code: content.replace(/foo/g, 'bar')
};
code: s.toString(),
map: s.generateMap()
}
}
}, {
filename: 'App.svelte'

@ -0,0 +1,369 @@
---
title: Accessibility warnings
---
Accessibility (shortened to a11y) isn't always easy to get right, but Svelte will help by warning you at compile time if you write inaccessible markup. However, keep in mind that many accessibility issues can only be identified at runtime using other automated tools and by manually testing your application.
Here is a list of accessibility checks Svelte will do for you.
---
### `a11y-accesskey`
Enforce no `accesskey` on element. Access keys are HTML attributes that allow web developers to assign keyboard shortcuts to elements. Inconsistencies between keyboard shortcuts and keyboard commands used by screen reader and keyboard-only users create accessibility complications. To avoid complications, access keys should not be used.
```sv
<!-- A11y: Avoid using accesskey -->
<div accessKey='z'></div>
```
---
### `a11y-aria-activedescendant-has-tabindex`
An element with `aria-activedescendant` must be tabbable, so it must either have an inherent `tabindex` or declare `tabindex` as an attribute.
```sv
<!-- A11y: Elements with attribute aria-activedescendant should have tabindex value -->
<div aria-activedescendant="some-id" />
```
---
### `a11y-aria-attributes`
Certain reserved DOM elements do not support ARIA roles, states and properties. This is often because they are not visible, for example `meta`, `html`, `script`, `style`. This rule enforces that these DOM elements do not contain the `aria-*` props.
```sv
<!-- A11y: <meta> should not have aria-* attributes -->
<meta aria-hidden="false">
```
---
### `a11y-autofocus`
Enforce that `autofocus` is not used on elements. Autofocusing elements can cause usability issues for sighted and non-sighted users alike.
```sv
<!-- A11y: Avoid using autofocus -->
<input autofocus>
```
---
### `a11y-click-events-have-key-events`
Enforce `on:click` is accompanied by at least one of the following: `on:keyup`, `on:keydown`, `on:keypress`. Coding for the keyboard is important for users with physical disabilities who cannot use a mouse, AT compatibility, and screenreader users.
This does not apply for interactive or hidden elements.
```sv
<!-- A11y: visible, non-interactive elements with an on:click event must be accompanied by an on:keydown, on:keyup, or on:keypress event. -->
<div on:click={() => {}} />
```
Note that the `keypress` event is now deprecated, so it is officially recommended to use either the `keyup` or `keydown` event instead, accordingly.
---
### `a11y-distracting-elements`
Enforces that no distracting elements are used. Elements that can be visually distracting can cause accessibility issues with visually impaired users. Such elements are most likely deprecated, and should be avoided.
The following elements are visually distracting: `<marquee>` and `<blink>`.
```sv
<!-- A11y: Avoid <marquee> elements -->
<marquee />
```
---
### `a11y-hidden`
Certain DOM elements are useful for screen reader navigation and should not be hidden.
```sv
<!-- A11y: <h2> element should not be hidden -->
<h2 aria-hidden="true">invisible header</h2>
```
---
### `a11y-img-redundant-alt`
Enforce img alt attribute does not contain the word image, picture, or photo. Screen readers already announce `img` elements as an image. There is no need to use words such as _image_, _photo_, and/or _picture_.
```sv
<img src="foo" alt="Foo eating a sandwich." />
<!-- aria-hidden, won't be announced by screen reader -->
<img src="bar" aria-hidden="true" alt="Picture of me taking a photo of an image" />
<!-- A11y: Screen readers already announce <img> elements as an image. -->
<img src="foo" alt="Photo of foo being weird." />
<!-- A11y: Screen readers already announce <img> elements as an image. -->
<img src="bar" alt="Image of me at a bar!" />
<!-- A11y: Screen readers already announce <img> elements as an image. -->
<img src="foo" alt="Picture of baz fixing a bug." />
```
---
### `a11y-incorrect-aria-attribute-type`
Enforce that only the correct type of value is used for aria attributes. For example, `aria-hidden`
should only receive a boolean.
```sv
<!-- A11y: The value of 'aria-hidden' must be exactly one of true or false -->
<div aria-hidden="yes"/>
```
---
### `a11y-invalid-attribute`
Enforce that attributes important for accessibility have a valid value. For example, `href` should not be empty, `'#'`, or `javascript:`.
```sv
<!-- A11y: '' is not a valid href attribute -->
<a href=''>invalid</a>
```
---
### `a11y-label-has-associated-control`
Enforce that a label tag has a text label and an associated control.
There are two supported ways to associate a label with a control:
- Wrapping a control in a label tag.
- Adding `for` to a label and assigning it the ID of an input on the page.
```sv
<label for="id">B</label>
<label>C <input type="text" /></label>
<!-- A11y: A form label must be associated with a control. -->
<label>A</label>
```
---
### `a11y-media-has-caption`
Providing captions for media is essential for deaf users to follow along. Captions should be a transcription or translation of the dialogue, sound effects, relevant musical cues, and other relevant audio information. Not only is this important for accessibility, but can also be useful for all users in the case that the media is unavailable (similar to `alt` text on an image when an image is unable to load).
The captions should contain all important and relevant information to understand the corresponding media. This may mean that the captions are not a 1:1 mapping of the dialogue in the media content. However, captions are not necessary for video components with the `muted` attribute.
```sv
<video><track kind="captions"/></video>
<audio muted></audio>
<!-- A11y: Media elements must have a <track kind=\"captions\"> -->
<video></video>
<!-- A11y: Media elements must have a <track kind=\"captions\"> -->
<video><track /></video>
```
---
### `a11y-misplaced-role`
Certain reserved DOM elements do not support ARIA roles, states and properties. This is often because they are not visible, for example `meta`, `html`, `script`, `style`. This rule enforces that these DOM elements do not contain the `role` props.
```sv
<!-- A11y: <meta> should not have role attribute -->
<meta role="tooltip">
```
---
### `a11y-misplaced-scope`
The scope attribute should only be used on `<th>` elements.
```sv
<!-- A11y: The scope attribute should only be used with <th> elements -->
<div scope="row" />
```
---
### `a11y-missing-attribute`
Enforce that attributes required for accessibility are present on an element. This includes the following checks:
- `<a>` should have an href (unless it's a [fragment-defining tag](https://github.com/sveltejs/svelte/issues/4697))
- `<area>` should have alt, aria-label, or aria-labelledby
- `<html>` should have lang
- `<iframe>` should have title
- `<img>` should have alt
- `<object>` should have title, aria-label, or aria-labelledby
- `<input type="image">` should have alt, aria-label, or aria-labelledby
```sv
<!-- A11y: <input type=\"image\"> element should have an alt, aria-label or aria-labelledby attribute -->
<input type="image">
<!-- A11y: <html> element should have a lang attribute -->
<html></html>
<!-- A11y: <a> element should have an href attribute -->
<a>text</a>
```
---
### `a11y-missing-content`
Enforce that heading elements (`h1`, `h2`, etc.) and anchors have content and that the content is accessible to screen readers
```sv
<!-- A11y: <a> element should have child content -->
<a href='/foo'></a>
<!-- A11y: <h1> element should have child content -->
<h1></h1>
```
---
### `a11y-mouse-events-have-key-events`
Enforce that `on:mouseover` and `on:mouseout` are accompanied by `on:focus` and `on:blur`, respectively. This helps to ensure that any functionality triggered by these mouse events is also accessible to keyboard users.
```sv
<!-- A11y: on:mouseover must be accompanied by on:focus -->
<div on:mouseover={handleMouseover} />
<!-- A11y: on:mouseout must be accompanied by on:blur -->
<div on:mouseout={handleMouseout} />
```
---
### `a11y-no-redundant-roles`
Some HTML elements have default ARIA roles. Giving these elements an ARIA role that is already set by the browser [has no effect](https://www.w3.org/TR/using-aria/#aria-does-nothing) and is redundant.
```sv
<!-- A11y: Redundant role 'button' -->
<button role="button" />
<!-- A11y: Redundant role 'img' -->
<img role="img" src="foo.jpg" />
```
---
### `a11y-no-interactive-element-to-noninteractive-role`
[WAI-ARIA](https://www.w3.org/TR/wai-aria-1.1/#usage_intro) roles should not be used to convert an interactive element to a non-interactive element. Non-interactive ARIA roles include `article`, `banner`, `complementary`, `img`, `listitem`, `main`, `region` and `tooltip`.
```sv
<!-- A11y: <textarea> cannot have role 'listitem' -->
<textarea role="listitem" />
```
---
### `a11y-no-noninteractive-element-to-interactive-role`
[WAI-ARIA](https://www.w3.org/TR/wai-aria-1.1/#usage_intro) roles should not be used to convert a non-interactive element to an interactive element. Interactive ARIA roles include `button`, `link`, `checkbox`, `menuitem`, `menuitemcheckbox`, `menuitemradio`, `option`, `radio`, `searchbox`, `switch` and `textbox`.
```sv
<!-- A11y: Non-interactive element <h3> cannot have interactive role 'searchbox' -->
<h3 role="searchbox">Button</h3>
```
---
### `a11y-no-noninteractive-tabindex`
Tab key navigation should be limited to elements on the page that can be interacted with.
```sv
<!-- A11y: noninteractive element cannot have nonnegative tabIndex value -->
<div tabindex='0' />
```
---
### `a11y-positive-tabindex`
Avoid positive `tabindex` property values. This will move elements out of the expected tab order, creating a confusing experience for keyboard users.
```sv
<!-- A11y: avoid tabindex values above zero -->
<div tabindex='1'/>
```
---
### `a11y-role-has-required-aria-props`
Elements with ARIA roles must have all required attributes for that role.
```sv
<!-- A11y: A11y: Elements with the ARIA role "checkbox" must have the following attributes defined: "aria-checked" -->
<span role="checkbox" aria-labelledby="foo" tabindex="0"></span>
```
---
### `a11y-role-supports-aria-props`
Elements with explicit or implicit roles defined contain only `aria-*` properties supported by that role.
```sv
<!-- A11y: The attribute 'aria-multiline' is not supported by the role 'link'. -->
<div role="link" aria-multiline />
<!-- A11y: The attribute 'aria-required' is not supported by the role 'listitem'. This role is implicit on the element <li>. -->
<li aria-required />
```
---
### `a11y-structure`
Enforce that certain DOM elements have the correct structure.
```sv
<!-- A11y: <figcaption> must be an immediate child of <figure> -->
<div>
<figcaption>Image caption</figcaption>
</div>
```
---
### `a11y-unknown-aria-attribute`
Enforce that only known ARIA attributes are used. This is based on the [WAI-ARIA States and Properties spec](https://www.w3.org/WAI/PF/aria-1.1/states_and_properties).
```sv
<!-- A11y: Unknown aria attribute 'aria-labeledby' (did you mean 'labelledby'?) -->
<input type="image" aria-labeledby="foo">
```
---
### `a11y-unknown-role`
Elements with ARIA roles must use a valid, non-abstract ARIA role. A reference to role definitions can be found at [WAI-ARIA](https://www.w3.org/TR/wai-aria/#role_definitions) site.
```sv
<!-- A11y: Unknown role 'toooltip' (did you mean 'tooltip'?) -->
<div role="toooltip"></div>
```

@ -1,5 +1,5 @@
<script>
let src = 'tutorial/image.gif';
let src = '/tutorial/image.gif';
let name = 'Rick Astley';
</script>

@ -10,8 +10,10 @@
<ul>
{#each cats as { id, name }, i}
<li><a target="_blank" href="https://www.youtube.com/watch?v={id}">
<li>
<a target="_blank" rel="noreferrer" href="https://www.youtube.com/watch?v={id}">
{i + 1}: {name}
</a></li>
</a>
</li>
{/each}
</ul>

@ -2,7 +2,7 @@
let promise = getRandomNumber();
async function getRandomNumber() {
const res = await fetch(`tutorial/random-number`);
const res = await fetch(`/tutorial/random-number`);
const text = await res.text();
if (res.ok) {

@ -10,7 +10,7 @@
{#if yes}
<p>Thank you. We will bombard your inbox and sell your personal details.</p>
{:else}
<p>You must opt in to continue. If you're not paying, you're the product.</p>
<p>You must opt-in to continue. If you're not paying, you're the product.</p>
{/if}
<button disabled={!yes}>

@ -1,5 +1,5 @@
<script>
import marked from 'marked';
import { marked } from 'marked';
let text = `Some words are *italic*, some are **bold**`;
</script>

@ -7,37 +7,35 @@
let showControls = true;
let showControlsTimeout;
function handleMousemove(e) {
// Used to track time of last mouse down event
let lastMouseDown;
function handleMove(e) {
// Make the controls visible, but fade out after
// 2.5 seconds of inactivity
clearTimeout(showControlsTimeout);
showControlsTimeout = setTimeout(() => showControls = false, 2500);
showControls = true;
if (!(e.buttons & 1)) return; // mouse not down
if (!duration) return; // video not loaded yet
if (e.type !== 'touchmove' && !(e.buttons & 1)) return; // mouse not down
const clientX = e.type === 'touchmove' ? e.touches[0].clientX : e.clientX;
const { left, right } = this.getBoundingClientRect();
time = duration * (e.clientX - left) / (right - left);
time = duration * (clientX - left) / (right - left);
}
function handleMousedown(e) {
// we can't rely on the built-in click event, because it fires
// after a drag — we have to listen for clicks ourselves
function handleMousedown(e) {
lastMouseDown = new Date();
}
function handleMouseup() {
function handleMouseup(e) {
if (new Date() - lastMouseDown < 300) {
if (paused) e.target.play();
else e.target.pause();
cancel();
}
function cancel() {
e.target.removeEventListener('mouseup', handleMouseup);
}
e.target.addEventListener('mouseup', handleMouseup);
setTimeout(cancel, 200);
}
function format(seconds) {
@ -52,14 +50,16 @@
</script>
<h1>Caminandes: Llamigos</h1>
<p>From <a href="https://cloud.blender.org/open-projects">Blender Open Projects</a>. CC-BY</p>
<p>From <a href="https://studio.blender.org/films">Blender Studio</a>. CC-BY</p>
<div>
<video
poster="https://sveltejs.github.io/assets/caminandes-llamigos.jpg"
src="https://sveltejs.github.io/assets/caminandes-llamigos.mp4"
on:mousemove={handleMousemove}
on:mousemove={handleMove}
on:touchmove|preventDefault={handleMove}
on:mousedown={handleMousedown}
on:mouseup={handleMouseup}
bind:currentTime={time}
bind:duration
bind:paused>

@ -49,7 +49,7 @@
width: 100%;
height: 100%;
background-color: #666;
-webkit-mask: url(svelte-logo-mask.svg) 50% 50% no-repeat;
mask: url(svelte-logo-mask.svg) 50% 50% no-repeat;
-webkit-mask: url(/svelte-logo-mask.svg) 50% 50% no-repeat;
mask: url(/svelte-logo-mask.svg) 50% 50% no-repeat;
}
</style>

@ -4,7 +4,7 @@
let photos = [];
onMount(async () => {
const res = await fetch(`https://jsonplaceholder.typicode.com/photos?_limit=20`);
const res = await fetch(`/tutorial/api/album`);
photos = await res.json();
});
</script>

@ -4,14 +4,14 @@
import Decrementer from './Decrementer.svelte';
import Resetter from './Resetter.svelte';
let count_value;
let countValue;
const unsubscribe = count.subscribe(value => {
count_value = value;
countValue = value;
});
</script>
<h1>The count is {count_value}</h1>
<h1>The count is {countValue}</h1>
<Incrementer/>
<Decrementer/>

@ -1,7 +1,7 @@
<script>
let visible = false;
function typewriter(node, { speed = 50 }) {
function typewriter(node, { speed = 1 }) {
const valid = (
node.childNodes.length === 1 &&
node.childNodes[0].nodeType === Node.TEXT_NODE
@ -12,7 +12,7 @@
}
const text = node.textContent;
const duration = text.length * speed;
const duration = text.length / (speed * 0.01);
return {
duration,
@ -30,7 +30,7 @@
</label>
{#if visible}
<p in:typewriter>
<p transition:typewriter>
The quick brown fox jumps over the lazy dog
</p>
{/if}

@ -56,8 +56,8 @@
>
<p class='credit'>
<a target="_blank" href="https://www.flickr.com/photos/{d.path}">via Flickr</a> &ndash;
<a target="_blank" href={d.license.url}>{d.license.name}</a>
<a target="_blank" rel="noreferrer" href="https://www.flickr.com/photos/{d.path}">via Flickr</a> &ndash;
<a target="_blank" rel="noreferrer" href={d.license.url}>{d.license.name}</a>
</p>
</div>
{/await}

@ -82,7 +82,6 @@
max-height: 95%;
max-width: 800px;
margin: auto;
padding: 10px;
border: 1px solid #333;
border-radius: 2px;
padding: 20px;

@ -38,9 +38,9 @@
<div class="chart" bind:clientWidth={width} bind:clientHeight={height}>
<svg>
<!-- y axis -->
<g class="axis y-axis" transform="translate(0,{padding.top})">
<g class="axis y-axis">
{#each yTicks as tick}
<g class="tick tick-{tick}" transform="translate(0, {yScale(tick) - padding.bottom})">
<g class="tick tick-{tick}" transform="translate(0, {yScale(tick)})">
<line x2="100%"></line>
<text y="-4">{tick} {tick === 20 ? ' per 1,000 population' : ''}</text>
</g>
@ -62,7 +62,7 @@
x="{xScale(i) + 2}"
y="{yScale(point.birthrate)}"
width="{barWidth - 4}"
height="{height - padding.bottom - yScale(point.birthrate)}"
height="{yScale(0) - yScale(point.birthrate)}"
></rect>
{/each}
</g>

@ -36,5 +36,10 @@ export default [
{ x: 2013, y: 5.35 },
{ x: 2014, y: 5.28 },
{ x: 2015, y: 4.63 },
{ x: 2016, y: 4.72 }
{ x: 2016, y: 4.72 },
{ x: 2017, y: 4.82 },
{ x: 2018, y: 4.79 },
{ x: 2019, y: 4.36 },
{ x: 2020, y: 4 },
{ x: 2021, y: 4.92 }
];

@ -1,39 +1,15 @@
<script>
import { spring } from 'svelte/motion';
import { pannable } from './pannable.js';
import { clickOutside } from "./click_outside.js";
const coords = spring({ x: 0, y: 0 }, {
stiffness: 0.2,
damping: 0.4
});
function handlePanStart() {
coords.stiffness = coords.damping = 1;
}
function handlePanMove(event) {
coords.update($coords => ({
x: $coords.x + event.detail.dx,
y: $coords.y + event.detail.dy
}));
}
function handlePanEnd(event) {
coords.stiffness = 0.2;
coords.damping = 0.4;
coords.set({ x: 0, y: 0 });
}
let showModal = true;
</script>
<div class="box"
use:pannable
on:panstart={handlePanStart}
on:panmove={handlePanMove}
on:panend={handlePanEnd}
style="transform:
translate({$coords.x}px,{$coords.y}px)
rotate({$coords.x * 0.2}deg)"
></div>
<button on:click={() => (showModal = true)}>Show Modal</button>
{#if showModal}
<div class="box" use:clickOutside on:outclick={() => (showModal = false)}>
Click outside me!
</div>
{/if}
<style>
.box {
@ -44,8 +20,13 @@
height: var(--height);
left: calc(50% - var(--width) / 2);
top: calc(50% - var(--height) / 2);
display: flex;
align-items: center;
padding: 8px;
border-radius: 4px;
background-color: #ff3e00;
cursor: move;
color: #fff;
text-align: center;
font-weight: bold;
}
</style>

@ -0,0 +1,15 @@
export function clickOutside(node) {
const handleClick = (event) => {
if (!node.contains(event.target)) {
node.dispatchEvent(new CustomEvent("outclick"));
}
};
document.addEventListener("click", handleClick, true);
return {
destroy() {
document.removeEventListener("click", handleClick, true);
}
};
}

@ -0,0 +1,51 @@
<script>
import { spring } from 'svelte/motion';
import { pannable } from './pannable.js';
const coords = spring({ x: 0, y: 0 }, {
stiffness: 0.2,
damping: 0.4
});
function handlePanStart() {
coords.stiffness = coords.damping = 1;
}
function handlePanMove(event) {
coords.update($coords => ({
x: $coords.x + event.detail.dx,
y: $coords.y + event.detail.dy
}));
}
function handlePanEnd(event) {
coords.stiffness = 0.2;
coords.damping = 0.4;
coords.set({ x: 0, y: 0 });
}
</script>
<div class="box"
use:pannable
on:panstart={handlePanStart}
on:panmove={handlePanMove}
on:panend={handlePanEnd}
style="transform:
translate({$coords.x}px,{$coords.y}px)
rotate({$coords.x * 0.2}deg)"
></div>
<style>
.box {
--width: 100px;
--height: 100px;
position: absolute;
width: var(--width);
height: var(--height);
left: calc(50% - var(--width) / 2);
top: calc(50% - var(--height) / 2);
border-radius: 4px;
background-color: #ff3e00;
cursor: move;
}
</style>

@ -0,0 +1,3 @@
{
"title": "A more complex action"
}

@ -41,7 +41,7 @@
line-height: 1.2;
}
.address { background-image: url(tutorial/icons/map-marker.svg) }
.email { background-image: url(tutorial/icons/email.svg) }
.address { background-image: url(/tutorial/icons/map-marker.svg) }
.email { background-image: url(/tutorial/icons/email.svg) }
.missing { color: #999 }
</style>

@ -43,4 +43,8 @@
background-color: #ff3e00;
color: white;
}
p {
pointer-events: none;
}
</style>

@ -4,12 +4,11 @@
let showModal = false;
</script>
<button on:click="{() => showModal = true}">
<button on:click={() => (showModal = true)}>
show modal
</button>
{#if showModal}
<Modal on:close="{() => showModal = false}">
<Modal bind:showModal>
<h2 slot="header">
modal
<small><em>adjective</em> mod·al \ˈmō-dəl\</small>
@ -17,7 +16,9 @@
<ol class="definition-list">
<li>of or relating to modality in logic</li>
<li>containing provisions as to the mode of procedure or the manner of taking effect —used of a contract or legacy</li>
<li>
containing provisions as to the mode of procedure or the manner of taking effect —used of a contract or legacy
</li>
<li>of or relating to a musical mode</li>
<li>of or relating to structure as opposed to substance</li>
<li>of, relating to, or constituting a grammatical form or category characteristically indicating predication</li>
@ -26,4 +27,3 @@
<a href="https://www.merriam-webster.com/dictionary/modal">merriam-webster.com</a>
</Modal>
{/if}

@ -1,80 +1,62 @@
<script>
import { createEventDispatcher, onDestroy } from 'svelte';
export let showModal; // boolean
const dispatch = createEventDispatcher();
const close = () => dispatch('close');
let dialog; // HTMLDialogElement
let modal;
const handle_keydown = e => {
if (e.key === 'Escape') {
close();
return;
}
if (e.key === 'Tab') {
// trap focus
const nodes = modal.querySelectorAll('*');
const tabbable = Array.from(nodes).filter(n => n.tabIndex >= 0);
let index = tabbable.indexOf(document.activeElement);
if (index === -1 && e.shiftKey) index = 0;
index += tabbable.length + (e.shiftKey ? -1 : 1);
index %= tabbable.length;
tabbable[index].focus();
e.preventDefault();
}
};
const previously_focused = typeof document !== 'undefined' && document.activeElement;
if (previously_focused) {
onDestroy(() => {
previously_focused.focus();
});
}
$: if (dialog && showModal) dialog.showModal();
</script>
<svelte:window on:keydown={handle_keydown}/>
<div class="modal-background" on:click={close}></div>
<div class="modal" role="dialog" aria-modal="true" bind:this={modal}>
<slot name="header"></slot>
<hr>
<slot></slot>
<hr>
<!-- svelte-ignore a11y-click-events-have-key-events -->
<dialog
bind:this={dialog}
on:close={() => (showModal = false)}
on:click|self={() => dialog.close()}
>
<div on:click|stopPropagation>
<slot name="header" />
<hr />
<slot />
<hr />
<!-- svelte-ignore a11y-autofocus -->
<button autofocus on:click={close}>close modal</button>
<button autofocus on:click={() => dialog.close()}>close modal</button>
</div>
</dialog>
<style>
.modal-background {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
dialog {
max-width: 32em;
border-radius: 0.2em;
border: none;
padding: 0;
}
dialog::backdrop {
background: rgba(0, 0, 0, 0.3);
}
.modal {
position: absolute;
left: 50%;
top: 50%;
width: calc(100vw - 4em);
max-width: 32em;
max-height: calc(100vh - 4em);
overflow: auto;
transform: translate(-50%,-50%);
dialog > div {
padding: 1em;
border-radius: 0.2em;
background: white;
}
dialog[open] {
animation: zoom 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes zoom {
from {
transform: scale(0.95);
}
to {
transform: scale(1);
}
}
dialog[open]::backdrop {
animation: fade 0.2s ease-out;
}
@keyframes fade {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
button {
display: block;
}

@ -1,9 +1,9 @@
<script>
import { onMount, setContext } from 'svelte';
import { onDestroy, setContext } from 'svelte';
import { mapbox, key } from './mapbox.js';
setContext(key, {
getMap: () => map
getMap: () => map,
});
export let lat;
@ -13,32 +13,31 @@
let container;
let map;
onMount(() => {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'https://unpkg.com/mapbox-gl/dist/mapbox-gl.css';
link.onload = () => {
function load() {
map = new mapbox.Map({
container,
style: 'mapbox://styles/mapbox/streets-v9',
center: [lon, lat],
zoom
zoom,
});
};
document.head.appendChild(link);
}
return () => {
map.remove();
link.parentNode.removeChild(link);
};
onDestroy(() => {
if (map) map.remove();
});
</script>
<svelte:head>
<link
rel="stylesheet"
href="https://unpkg.com/mapbox-gl/dist/mapbox-gl.css"
on:load={load}
/>
</svelte:head>
<div bind:this={container}>
{#if map}
<slot></slot>
<slot />
{/if}
</div>

@ -3,7 +3,7 @@
$: type = name.slice(name.lastIndexOf('.') + 1);
</script>
<span style="background-image: url(tutorial/icons/{type}.svg)">{name}</span>
<span style="background-image: url(/tutorial/icons/{type}.svg)">{name}</span>
<style>
span {

@ -1,5 +1,6 @@
<script>
import File from './File.svelte';
import {slide} from 'svelte/transition'
export let expanded = false;
export let name;
@ -13,7 +14,7 @@
<span class:expanded on:click={toggle}>{name}</span>
{#if expanded}
<ul>
<ul transition:slide={{duration:300}}>
{#each files as file}
<li>
{#if file.type === 'folder'}
@ -29,14 +30,14 @@
<style>
span {
padding: 0 0 0 1.5em;
background: url(tutorial/icons/folder.svg) 0 0.1em no-repeat;
background: url(/tutorial/icons/folder.svg) 0 0.1em no-repeat;
background-size: 1em 1em;
font-weight: bold;
cursor: pointer;
}
.expanded {
background-image: url(tutorial/icons/folder-open.svg);
background-image: url(/tutorial/icons/folder-open.svg);
}
ul {

@ -0,0 +1,12 @@
<script>
const options = ['h1', 'h3', 'p'];
let selected = options[0];
</script>
<select bind:value={selected}>
{#each options as option}
<option value={option}>{option}</option>
{/each}
</select>
<svelte:element this={selected}>I'm a {selected} tag</svelte:element>

@ -7,7 +7,7 @@
<svelte:window bind:scrollY={y}/>
<a class="parallax-container" href="https://www.firewatchgame.com">
{#each [0, 1, 2, 3, 4, 5, 6, 7, 8] as layer}
{#each layers as layer}
<img
style="transform: translate(0,{-y * layer / (layers.length - 1)}px)"
src="https://www.firewatchgame.com/images/parallax/parallax{layer}.png"

@ -5,6 +5,18 @@
const handleMouseleave = () => hereKitty = false;
</script>
<svelte:body
on:mouseenter={handleMouseenter}
on:mouseleave={handleMouseleave}
/>
<!-- creative commons BY-NC http://www.pngall.com/kitten-png/download/7247 -->
<img
class:curious={hereKitty}
alt="Kitten wants to know what's going on"
src="/tutorial/kitten.png"
>
<style>
img {
position: absolute;
@ -23,15 +35,3 @@
overflow: hidden;
}
</style>
<svelte:body
on:mouseenter={handleMouseenter}
on:mouseleave={handleMouseleave}
/>
<!-- creative commons BY-NC http://www.pngall.com/kitten-png/download/7247 -->
<img
class:curious={hereKitty}
alt="Kitten wants to know what's going on"
src="tutorial/kitten.png"
>

@ -1,5 +0,0 @@
<svelte:head>
<link rel="stylesheet" href="tutorial/dark-theme.css">
</svelte:head>
<h1>Hello world!</h1>

@ -0,0 +1,5 @@
<svelte:head>
<link rel="stylesheet" href="/tutorial/dark-theme.css">
</svelte:head>
<h1>Hello world!</h1>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save