Merge branch 'master' into gh-3780

gh-3780
Simon H 1 year ago committed by GitHub
commit 3a675797ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -13,4 +13,3 @@ insert_final_newline = false
[{package.json,.travis.yml,.eslintrc.json}]
indent_style = space
indent_size = 2

@ -1,7 +1,10 @@
**/_actual.js
**/expected.js
_output
test/*/samples/*/output.js
node_modules
# automatically generated
internal_exports.ts
# output files
animate/*.js

@ -1,69 +1,6 @@
module.exports = {
root: true,
rules: {
indent: 'off',
'no-unused-vars': 'off',
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,
'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': 'off',
'@typescript-eslint/indent': 'off',
'@typescript-eslint/camelcase': 'off',
'@typescript-eslint/no-use-before-define': 'off',
'@typescript-eslint/array-type': ['error', 'array-simple'],
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/explicit-member-accessibility': 'off',
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^_'
}
],
'@typescript-eslint/no-object-literal-type-assertion': [
'error',
{
allowAsParameter: true
}
],
'@typescript-eslint/no-unused-vars': 'off'
},
globals: {
globalThis: false
},
env: {
es6: true,
browser: true,
node: true,
mocha: true
},
extends: [
'eslint:recommended',
'plugin:import/errors',
'plugin:import/warnings',
'plugin:import/typescript',
'plugin:@typescript-eslint/recommended'
],
parserOptions: {
ecmaVersion: 9,
sourceType: 'module'
},
plugins: ['svelte3'],
extends: '@sveltejs',
settings: {
'import/core-modules': [
'svelte',
@ -73,20 +10,5 @@ module.exports = {
'estree'
],
'svelte3/compiler': require('./compiler')
},
overrides: [
{
files: ['*.js'],
rules: {
'@typescript-eslint/no-var-requires': 'off'
}
},
{
files: ['*.svelte'],
processor: 'svelte3/svelte3',
rules: {
'@typescript-eslint/indent': 'off'
}
}
]
}
};

3
.gitattributes vendored

@ -0,0 +1,3 @@
/site/** -linguist-detectable
/test/**/samples/** -linguist-detectable
/**/*.svelte linguist-detectable

@ -0,0 +1 @@
open_collective: svelte

@ -8,10 +8,13 @@ the issue. One way we prioritize issues is by the number of :+1: reactions on
their descriptions. Please DO NOT add `+1` or :+1: comments.
### Feature requests and proposals
We're excited to hear how we can make Svelte better. Please add as much detail
as you can on your use case.
as you can on your use case. To propose an implementation of a large feature or
change, please create an [RFC](https://github.com/sveltejs/rfcs).
### Bugs
If you're filing an issue about a bug please include as much information
as you can including the following.

@ -1,52 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: 'Bug'
assignees: ''
---
**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:**
- 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,23 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: 'New Feature'
assignees: ''
---
**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,8 +1,8 @@
### Before submitting the PR, please make sure you do the following
- [ ] It's really useful if your PR relates to an outstanding issue, so please reference it in your PR, or create an explanatory one for discussion. In many cases features are absent for a reason.
- [ ] This message body should clearly illustrate what problems it solves. If there are related issues, remember to reference them.
- [ ] Ideally, include a test that fails without this PR but passes with it. PRs will only be merged once they pass CI. (Remember to `npm run lint`!)
- [ ] 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.
### Tests
- [ ] Run the tests tests with `npm test` or `yarn test`)
- [ ] Run the tests with `npm test` and lint the project with `npm run lint`

@ -1,25 +1,101 @@
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]
node-version: [8, 10, 12, 14, 16, 18]
os: [ubuntu-latest, windows-latest, macOS-latest]
steps:
- run: git config --global core.autocrlf false
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: npm install
- run: npm test
env:
CI: true
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: npm
- name: Download build assets
uses: actions/download-artifact@v3
id: download-artifact
with:
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
env:
SKIP_PREPARE: true
- run: npm run test:integration
env:
CI: true
Lint:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
cache: npm
- run: 'npm i && npm run lint'
Unit:
runs-on: ${{ matrix.os }}
timeout-minutes: 10
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macOS-latest]
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
- run: 'npm i && npm run lint'
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
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 }}

23
.gitignore vendored

@ -1,12 +1,14 @@
.idea
.DS_Store
.nyc_output
.vscode
node_modules
*.map
/src/compiler/compile/internal_exports.ts
/compiler.d.ts
/compiler.*js
/index.*js
/ssr.*js
/action
/internal
/store
/easing
@ -14,22 +16,9 @@ node_modules
/transition
/animate
/scratch/
/coverage/
/coverage.lcov
/test/sourcemaps/samples/*/output.js
/test/sourcemaps/samples/*/output.js.map
/test/sourcemaps/samples/*/output.css
/test/sourcemaps/samples/*/output.css.map
/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/scripts/svelte-app
/site/src/routes/_contributors.js
.eslintcache

@ -0,0 +1,14 @@
const is_unit_test = process.env.UNIT_TEST;
module.exports = {
file: is_unit_test ? [] : ['test/test.ts'],
require: [
'sucrase/register'
]
};
// 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');
}

@ -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');
}

@ -1,3 +0,0 @@
useTabs: true
singleQuote: true
trailingComma: es5

@ -1,5 +1,854 @@
# Svelte changelog
## Unreleased
* Add a11y warnings:
* `aria-activedescendant-has-tabindex`: elements with `aria-activedescendant` need to 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))
* Omit a11y warning on `<video>` tags with `aria-hidden="true"` ([#7874](https://github.com/sveltejs/svelte/issues/7874))
* Omit a11y "no child content" warning on elements with `aria-label` ([#8299](https://github.com/sveltejs/svelte/pull/8299))
* Omit a11y warnings on `<svelte:element>` ([#7939](https://github.com/sveltejs/svelte/issues/7939))
* Make `noreferrer` warning less zealous ([#6289](https://github.com/sveltejs/svelte/issues/6289))
* `trusted-types` CSP compatibility for Web Components ([#8134](https://github.com/sveltejs/svelte/issues/8134))
* Add `data-sveltekit-replacestate` and `data-sveltekit-keepfocus` attribute typings ([#8281](https://github.com/sveltejs/svelte/issues/8281))
* Don't throw when calling `unsubscribe` twice ([#8186](https://github.com/sveltejs/svelte/pull/8186))
* Detect unused empty attribute CSS selectors ([#8042](https://github.com/sveltejs/svelte/issues/8042))
* Simpler output for reactive statements if dependencies are all static ([#7942](https://github.com/sveltejs/svelte/pull/7942))
* Flush remaining `afterUpdate` calls before `onDestroy` ([#7476](https://github.com/sveltejs/svelte/issues/7476))
* Check value equality for `input` types `url` and `search` ([#7027](https://github.com/sveltejs/svelte/issues/7027))
* Compute node dimensions directly before crossfading ([#4111](https://github.com/sveltejs/svelte/issues/4111))
* Add `readonly` method to convert `writable` store to readonly ([#6518](https://github.com/sveltejs/svelte/pull/6518))
* Ensure `bind:offsetHeight` updates initially ([#4233](https://github.com/sveltejs/svelte/issues/4233))
* Better handling of `inert` attribute ([#7500](https://github.com/sveltejs/svelte/issues/7500))
* Clear inputs when `bind:group` to `undefined` ([#8214](https://github.com/sveltejs/svelte/issues/8214))
* Ensure nested arrays can change at the same time ([#8282](https://github.com/sveltejs/svelte/issues/8282))
* Reduce use of template literals in SSR output for better performance ([#7539](https://github.com/sveltejs/svelte/pull/7539))
* Allow assigning to property of const while destructuring ([#7964](https://github.com/sveltejs/svelte/issues/7964))
* Don't set selected options if value is unbound or not passed ([#5644](https://github.com/sveltejs/svelte/issues/5644))
* Ensure `<input>` value persists when swapping elements with spread attributes in an `#each` block ([#7578](https://github.com/sveltejs/svelte/issues/7578))
* Select first enabled option by default when initial value is undefined ([#7041](https://github.com/sveltejs/svelte/issues/7041))
* Fix race condition on `svelte:element` with transitions ([#7948](https://github.com/sveltejs/svelte/issues/7948))
* Optimise `<svelte:element>` output code for static tag and static attribute ([#8161](https://github.com/sveltejs/svelte/pull/8161))
* Decode html entities correctly ([#8026](https://github.com/sveltejs/svelte/issues/8026))
* Handle `{@html}` tags inside `<template>` tags ([#7364](https://github.com/sveltejs/svelte/pull/7364))
* Introduce parameter to allow for horizontal slide transition ([#6182](https://github.com/sveltejs/svelte/issues/6182))
* Add `naturalWidth` and `naturalHeight` bindings ([#7771](https://github.com/sveltejs/svelte/issues/7771))
* make `<!-- svelte-ignore ... -->` work above components ([#8082](https://github.com/sveltejs/svelte/issues/8082))
* add global compound selector validation ([#6272](https://github.com/sveltejs/svelte/issues/6272))
* add `stopImmediatePropagation` event modifier ([#5085](https://github.com/sveltejs/svelte/issues/5085))
* add `readyState` binding for media elements ([#6666](https://github.com/sveltejs/svelte/issues/6666))
* call `<svelte:component>` update to `this` only when it's dirty ([#4129](https://github.com/sveltejs/svelte/issues/4129))
* support exclusively special characters in component filenames ([#7143](https://github.com/sveltejs/svelte/issues/7143))
## 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))
* 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
* Allow root-level context to be passed to the component constructor ([#6032](https://github.com/sveltejs/svelte/pull/6032))
## 3.36.0
* Add `this: void` typing to store functions ([#6094](https://github.com/sveltejs/svelte/pull/6094))
* Export `Spring`, `Tweened` and `EasingFunction` interfaces ([#6070](https://github.com/sveltejs/svelte/issues/6070), [#6056](https://github.com/sveltejs/svelte/pull/6056))
* Export interfaces for transition parameters ([#5207](https://github.com/sveltejs/svelte/issues/5207))
* Export store's useful TypeScript definitions ([#5864](https://github.com/sveltejs/svelte/issues/5864))
* Fix previous breaking change to `svelte/preprocess` types location ([#6100](https://github.com/sveltejs/svelte/pull/6100))
* Fix missing slotted elements in AST ([#6066](https://github.com/sveltejs/svelte/issues/6066))
## 3.35.0
* Implement slotted components and `<svelte:fragment slot="...">` ([#1037](https://github.com/sveltejs/svelte/issues/1037), [#2079](https://github.com/sveltejs/svelte/issues/2079))
* Fix reactivity bug where `slot="..."` is specified after attributes that should be reactive ([#5626](https://github.com/sveltejs/svelte/issues/5626))
## 3.34.0
* Add a `cssHash` option for controlling the classname used for CSS scoping ([#570](https://github.com/sveltejs/svelte/issues/570))
## 3.33.0
* In custom elements, call `onMount` functions when connecting and clean up when disconnecting ([#1152](https://github.com/sveltejs/svelte/issues/1152), [#2227](https://github.com/sveltejs/svelte/issues/2227), [#4522](https://github.com/sveltejs/svelte/pull/4522))
* Allow destructured defaults to refer to other variables ([#5066](https://github.com/sveltejs/svelte/issues/5066))
* Do not emit `contextual-store` warnings for function parameters or declared variables ([#6008](https://github.com/sveltejs/svelte/pull/6008))
## 3.32.3
* Fix removal of lone `:host` selectors ([#5982](https://github.com/sveltejs/svelte/issues/5982))
## 3.32.2
* Fix unnecessary additional invalidation with `<Component bind:prop={obj.foo}/>` ([#3075](https://github.com/sveltejs/svelte/issues/3075), [#4447](https://github.com/sveltejs/svelte/issues/4447), [#5555](https://github.com/sveltejs/svelte/issues/5555))
* Fix scoping of selectors with `:global()` and `~` sibling combinators ([#5499](https://github.com/sveltejs/svelte/issues/5499))
* Fix removal of `:host` selectors as unused when compiling to a custom element ([#5946](https://github.com/sveltejs/svelte/issues/5946))
## 3.32.1
* Warn when using `module` variables reactively, and close weird reactivity loophole ([#5847](https://github.com/sveltejs/svelte/pull/5847))
* Throw a parser error for `class:` directives with an empty class name ([#5858](https://github.com/sveltejs/svelte/issues/5858))
* Fix extraneous store subscription in SSR mode ([#5883](https://github.com/sveltejs/svelte/issues/5883))
* Don't emit update code for `class:` directives whose expression is not dynamic ([#5919](https://github.com/sveltejs/svelte/issues/5919))
* Fix type inference for derived stores ([#5935](https://github.com/sveltejs/svelte/pull/5935))
* Make parameters of built-in animations and transitions optional ([#5936](https://github.com/sveltejs/svelte/pull/5936))
* Make `SvelteComponentDev` typings more forgiving ([#5937](https://github.com/sveltejs/svelte/pull/5937))
* Fix `foreign` elements incorrectly disallowing `bind:this` ([#5942](https://github.com/sveltejs/svelte/pull/5942))
## 3.32.0
* Allow multiple instances of the same action on an element ([#5516](https://github.com/sveltejs/svelte/issues/5516))
* Support `foreign` namespace, which disables certain HTML5-specific behaviour and checks ([#5652](https://github.com/sveltejs/svelte/pull/5652))
* Support inline comment sourcemaps in code from preprocessors ([#5854](https://github.com/sveltejs/svelte/pull/5854))
## 3.31.2
* Rework SSR store handling to subscribe and unsubscribe as in DOM mode ([#3375](https://github.com/sveltejs/svelte/issues/3375), [#3582](https://github.com/sveltejs/svelte/issues/3582), [#3636](https://github.com/sveltejs/svelte/issues/3636))
* Fix error when removing elements that are already transitioning out ([#5789](https://github.com/sveltejs/svelte/issues/5789), [#5808](https://github.com/sveltejs/svelte/issues/5808))
* Fix duplicate content race condition with `{#await}` blocks and out transitions ([#5815](https://github.com/sveltejs/svelte/issues/5815))
* Deconflict variable names used for contextual actions ([#5834](https://github.com/sveltejs/svelte/issues/5834))
## 3.31.1
* Fix scrolling of element with resize listener by making the `<iframe>` have `z-index: -1` ([#5448](https://github.com/sveltejs/svelte/issues/5448))
* Fix location of automatically declared reactive variables ([#5749](https://github.com/sveltejs/svelte/issues/5749))
* Warn when using `className` or `htmlFor` attributes ([#5777](https://github.com/sveltejs/svelte/issues/5777))
* Fix checkbox `bind:group` in keyed `{#each}` where the array can be reordered ([#5779](https://github.com/sveltejs/svelte/issues/5779))
* Fix checkbox `bind:group` in nested `{#each}` contexts ([#5811](https://github.com/sveltejs/svelte/issues/5811))
* Add graphics roles as known ARIA roles ([#5822](https://github.com/sveltejs/svelte/pull/5822))
* Fix local transitions if a parent has a cancelled outro transition ([#5829](https://github.com/sveltejs/svelte/issues/5829))
* Support `use:obj.some.deep.function` as actions ([#5844](https://github.com/sveltejs/svelte/issues/5844))
## 3.31.0
* Use a separate `SvelteComponentTyped` interface for typed components ([#5738](https://github.com/sveltejs/svelte/pull/5738))
## 3.30.1
* Support consuming decoded sourcemaps as created by the `source-map` library's `SourceMapGenerator` ([#5722](https://github.com/sveltejs/svelte/issues/5722))
* Actually export `hasContext` ([#5726](https://github.com/sveltejs/svelte/issues/5726))
## 3.30.0
* Add a typed `SvelteComponent` interface ([#5431](https://github.com/sveltejs/svelte/pull/5431))
* Support spread into `<slot>` props ([#5456](https://github.com/sveltejs/svelte/issues/5456))
* Fix setting reactive dependencies which don't appear in the template to `undefined` ([#5538](https://github.com/sveltejs/svelte/issues/5538))
* Support preprocessor sourcemaps during compilation ([#5584](https://github.com/sveltejs/svelte/pull/5584))
* Fix ordering of elements when using `{#if}` inside `{#key}` ([#5680](https://github.com/sveltejs/svelte/issues/5680))
* Add `hasContext` lifecycle function ([#5690](https://github.com/sveltejs/svelte/pull/5690))
* Fix missing `walk` types in `svelte/compiler` ([#5696](https://github.com/sveltejs/svelte/pull/5696))
## 3.29.7
* Include `./register` in exports map ([#5670](https://github.com/sveltejs/svelte/issues/5670))
## 3.29.6
* Include `./package.json` in export map ([#5659](https://github.com/sveltejs/svelte/issues/5659))
## 3.29.5
* Fix `$$props` and `$$restProps` when compiling to a custom element ([#5482](https://github.com/sveltejs/svelte/issues/5482))
* Include an export map in `package.json` ([#5556](https://github.com/sveltejs/svelte/issues/5556))
* Fix function calls in `<slot>` props that use contextual values ([#5565](https://github.com/sveltejs/svelte/issues/5565))
* Fix handling aborted transitions in `{:else}` blocks ([#5573](https://github.com/sveltejs/svelte/issues/5573))
* Add `Element` and `Node` to known globals ([#5586](https://github.com/sveltejs/svelte/issues/5586))
* Fix `$$slots` when compiling to custom elements ([#5594](https://github.com/sveltejs/svelte/issues/5594))
* Fix internal `import`s so that we're exposing a valid ES module ([#5617](https://github.com/sveltejs/svelte/issues/5617))
## 3.29.4
* Fix code generation error with `??` alongside logical operators ([#5558](https://github.com/sveltejs/svelte/issues/5558))
## 3.29.3
* Hopefully actually republish with proper UMD build for use in the REPL
## 3.29.2
* Republish with proper UMD build for use in the REPL
## 3.29.1
* Fix compiler hanging on `<slot slot="...">` ([#5475](https://github.com/sveltejs/svelte/issues/5475))
* Fix types on `get` function in `svelte/store` ([#5483](https://github.com/sveltejs/svelte/pull/5483))
* Add missing `end` field on ASTs for non-top-level `<style>` elements ([#5487](https://github.com/sveltejs/svelte/pull/5487))
* Fix `{#if}` inside `{#await}` with destructuring ([#5508](https://github.com/sveltejs/svelte/issues/5508))
* Fix types on lifecycle hooks ([#5529](https://github.com/sveltejs/svelte/pull/5529))
## 3.29.0
* Support `<slot slot="...">` ([#2079](https://github.com/sveltejs/svelte/issues/2079))
* Fix unmounting components with a bidirectional transition with a delay ([#4954](https://github.com/sveltejs/svelte/issues/4954))
* Add types to `get` function in `svelte/store` ([#5269](https://github.com/sveltejs/svelte/pull/5269))
* Add a warning when a component looks like it's trying to use another component without beginning with a capital letter ([#5302](https://github.com/sveltejs/svelte/pull/5302))
* Add `EventSource` to known globals ([#5463](https://github.com/sveltejs/svelte/issues/5463))
* Fix compiler exception with `~`/`+` combinators and `{...spread}` attributes ([#5465](https://github.com/sveltejs/svelte/issues/5465))
## 3.28.0
* Add `{#key}` block for keying arbitrary content on an expression ([#1469](https://github.com/sveltejs/svelte/issues/1469))
## 3.27.0
* Add `|nonpassive` event modifier, explicitly passing `passive: false` ([#2068](https://github.com/sveltejs/svelte/issues/2068))
* Scope CSS selectors with `~` and `+` combinators ([#3104](https://github.com/sveltejs/svelte/issues/3104))
* Fix keyed `{#each}` not reacting to key changing ([#5444](https://github.com/sveltejs/svelte/issues/5444))
* Fix destructuring into store values ([#5449](https://github.com/sveltejs/svelte/issues/5449))
* Fix erroneous `missing-declaration` warning with `use:obj.method` ([#5451](https://github.com/sveltejs/svelte/issues/5451))
## 3.26.0
* Support `use:obj.method` as actions ([#3935](https://github.com/sveltejs/svelte/issues/3935))
* Support `_` as numeric separator ([#5407](https://github.com/sveltejs/svelte/issues/5407))
* Fix assignments to properties on store values ([#5412](https://github.com/sveltejs/svelte/issues/5412))
* Add special style scoping handling of `[open]` selectors on `<details>` elements ([#5421](https://github.com/sveltejs/svelte/issues/5421))
* Support `import.meta` in template expressions ([#5422](https://github.com/sveltejs/svelte/issues/5422))
## 3.25.1
* Fix specificity of certain styles involving a child selector ([#4795](https://github.com/sveltejs/svelte/issues/4795))
* Fix transitions that are parameterised with stores ([#5244](https://github.com/sveltejs/svelte/issues/5244))
* Fix scoping of styles involving child selector and `*` ([#5370](https://github.com/sveltejs/svelte/issues/5370))
* Fix destructuring which reassigns stores ([#5388](https://github.com/sveltejs/svelte/issues/5388))
* Fix `{#await}`s with no `{:catch}` getting stuck unresolved if the promise rejects ([#5401](https://github.com/sveltejs/svelte/issues/5401))
## 3.25.0
* Use `null` rather than `undefined` for coerced bound value of `<input type="number">` ([#1701](https://github.com/sveltejs/svelte/issues/1701))
* Expose object of which slots have received content in `$$slots` ([#2106](https://github.com/sveltejs/svelte/issues/2106))
* Correctly disallow using lifecycle hooks after synchronous component initialisation ([#4259](https://github.com/sveltejs/svelte/issues/4259), [#4899](https://github.com/sveltejs/svelte/issues/4899))
* Re-throw an unhandled rejection when an `{#await}` block with no `{:catch}` gets a rejection ([#5129](https://github.com/sveltejs/svelte/issues/5129))
* Add types to `createEventDispatcher` ([#5211](https://github.com/sveltejs/svelte/issues/5211))
* In SSR mode, do not automatically declare variables for reactive assignments to member expressions ([#5247](https://github.com/sveltejs/svelte/issues/5247))
* Include selector in message of `unused-css-selector` warning ([#5252](https://github.com/sveltejs/svelte/issues/5252))
* Fix using `<Namespaced.Component/>`s in child `{#await}`/`{#each}` contexts ([#5255](https://github.com/sveltejs/svelte/issues/5255))
* Fix using `<svelte:component>` in `{:catch}` ([#5259](https://github.com/sveltejs/svelte/issues/5259))
* Fix setting one-way bound `<input>` `value` to `undefined` when it has spread attributes ([#5270](https://github.com/sveltejs/svelte/issues/5270))
* Fix deep two-way bindings inside an `{#each}` involving a store ([#5286](https://github.com/sveltejs/svelte/issues/5286))
* Use valid XHTML for elements that are optimised and inserted with `.innerHTML` ([#5315](https://github.com/sveltejs/svelte/issues/5315))
* Fix reactivity of `$$props` in slot fallback content ([#5367](https://github.com/sveltejs/svelte/issues/5367))
## 3.24.1
* Prevent duplicate invalidation with certain two-way component bindings ([#3180](https://github.com/sveltejs/svelte/issues/3180), [#5117](https://github.com/sveltejs/svelte/issues/5117), [#5144](https://github.com/sveltejs/svelte/issues/5144))
* Fix reactivity when passing `$$props` to a `<slot>` ([#3364](https://github.com/sveltejs/svelte/issues/3364))
* Fix transitions on `{#each}` `{:else}` ([#4970](https://github.com/sveltejs/svelte/issues/4970))
* Fix unneeded invalidation of `$$props` and `$$restProps` ([#4993](https://github.com/sveltejs/svelte/issues/4993), [#5118](https://github.com/sveltejs/svelte/issues/5118))
* Provide better compiler error message when mismatched tags are due to autoclosing of tags ([#5049](https://github.com/sveltejs/svelte/issues/5049))
* Add `a11y-label-has-associated-control` warning ([#5074](https://github.com/sveltejs/svelte/pull/5074))
* Add `a11y-media-has-caption` warning ([#5075](https://github.com/sveltejs/svelte/pull/5075))
* Fix `bind:group` when using contextual reference ([#5174](https://github.com/sveltejs/svelte/issues/5174))
## 3.24.0
* Support nullish coalescing (`??`) and optional chaining (`?.`) operators ([#1972](https://github.com/sveltejs/svelte/issues/1972))
* Support `import.meta` ([#4379](https://github.com/sveltejs/svelte/issues/4379))
* Fix only setting `<input>` values when they're changed when there are spread attributes ([#4418](https://github.com/sveltejs/svelte/issues/4418))
* Fix placement of `{@html}` when used at the root of a slot, at the root of a component, or in `<svelte:head>` ([#5012](https://github.com/sveltejs/svelte/issues/5012), [#5071](https://github.com/sveltejs/svelte/pull/5071))
* Fix certain handling of two-way bound `contenteditable` elements ([#5018](https://github.com/sveltejs/svelte/issues/5018))
* Fix handling of `import`ed value that is used as a store and is also mutated ([#5019](https://github.com/sveltejs/svelte/issues/5019))
* Do not display `a11y-missing-content` warning on elements with `contenteditable` bindings ([#5020](https://github.com/sveltejs/svelte/issues/5020))
* Fix handling of `this` in inline function expressions in the template ([#5033](https://github.com/sveltejs/svelte/issues/5033))
* Fix collapsing HTML with static content ([#5040](https://github.com/sveltejs/svelte/issues/5040))
* Prevent use of `$store` at compile time when top-level `store` has been shadowed ([#5048](https://github.com/sveltejs/svelte/issues/5048))
* Update `<select>` with one-way `value` binding when the available `<option>`s change ([#5051](https://github.com/sveltejs/svelte/issues/5051))
* Fix published `tweened` types so the `.set()` and `.update()` options are optional ([#5062](https://github.com/sveltejs/svelte/issues/5062))
* Fix contextual `bind:this` inside `{#each}` block ([#5067](https://github.com/sveltejs/svelte/issues/5067))
* Preprocess self-closing `<script>` and `<style>` tags ([#5080](https://github.com/sveltejs/svelte/issues/5080))
* Fix types for animation- and transition-related param objects so each param is optional ([#5083](https://github.com/sveltejs/svelte/pull/5083))
## 3.23.2
* Fix `bind:group` inside `{#each}` ([#3243](https://github.com/sveltejs/svelte/issues/3243))
* Don't crash when using an arrow function as a statement ([#4617](https://github.com/sveltejs/svelte/issues/4617))
* Deconflict `bind:this` variable ([#4636](https://github.com/sveltejs/svelte/issues/4636))
## 3.23.1
* Fix checkbox `bind:group` when multiple options have the same value ([#4397](https://github.com/sveltejs/svelte/issues/4397))
* Fix `bind:this` to the value of an `{#each}` block ([#4517](https://github.com/sveltejs/svelte/issues/4517))
* Fix reactivity when assigning to contextual `{#each}` variable ([#4574](https://github.com/sveltejs/svelte/issues/4574), [#4744](https://github.com/sveltejs/svelte/issues/4744))
* Fix binding to contextual `{#each}` values that shadow outer names ([#4757](https://github.com/sveltejs/svelte/issues/4757))
* Work around EdgeHTML DOM issue when removing attributes during hydration ([#4911](https://github.com/sveltejs/svelte/pull/4911))
* Throw CSS parser error when `:global()` does not contain a selector ([#4930](https://github.com/sveltejs/svelte/issues/4930))
## 3.23.0
* Update `<select>` with `bind:value` when the available `<option>`s change ([#1764](https://github.com/sveltejs/svelte/issues/1764))
* Add `muted` binding for media elements ([#2998](https://github.com/sveltejs/svelte/issues/2998))
* Fix inconsistencies when setting a two-way bound `<input>` to `undefined` ([#3569](https://github.com/sveltejs/svelte/issues/3569))
* Fix setting `<select multiple>` when there are spread attributes ([#4392](https://github.com/sveltejs/svelte/issues/4392))
* Fix let-less `<slot>` with context overflow ([#4624](https://github.com/sveltejs/svelte/issues/4624))
* Fix resize listening on certain older browsers ([#4752](https://github.com/sveltejs/svelte/issues/4752))
* Add `a11y-no-onchange` warning ([#4788](https://github.com/sveltejs/svelte/pull/4788))
* Fix `use:` actions being recreated when a keyed `{#each}` is reordered ([#4693](https://github.com/sveltejs/svelte/issues/4693))
* Fix `{@html}` when using tags that can only appear inside certain tags ([#4852](https://github.com/sveltejs/svelte/issues/4852))
* Fix reactivity when binding directly to `{#each}` context ([#4879](https://github.com/sveltejs/svelte/issues/4879))
## 3.22.3
* Support default values and trailing commas in destructuring `{#await}` ([#4560](https://github.com/sveltejs/svelte/issues/4560), [#4810](https://github.com/sveltejs/svelte/issues/4810))
* Fix handling of `tweened` store when set using `duration: 0` ([#4799](https://github.com/sveltejs/svelte/issues/4799), [#4846](https://github.com/sveltejs/svelte/issues/4846))
* Fix setting `value` attribute with `bind:group` and attribute spread ([#4803](https://github.com/sveltejs/svelte/issues/4803))
* Fix issue with compound `{#if}` block involving static condition, dynamic condition, and inline component ([#4840](https://github.com/sveltejs/svelte/issues/4840))
* Update a11y warnings per ARIA 1.2 working draft ([#4844](https://github.com/sveltejs/svelte/issues/4844))
## 3.22.2
* Fix compiler exception with `a11y-img-redundant-alt` and value-less `alt` attribute ([#4777](https://github.com/sveltejs/svelte/issues/4777))
## 3.22.1
* Fix compiler exception with `a11y-img-redundant-alt` and dynamic `alt` attribute ([#4770](https://github.com/sveltejs/svelte/issues/4770))
## 3.22.0
* Fix misaligned line numbers in source maps ([#3906](https://github.com/sveltejs/svelte/issues/3906))
* Make setting a `tweened` store using `duration: 0` instantly update the value ([#4399](https://github.com/sveltejs/svelte/issues/4399))
* Fix reactivity with imported values that are then mutated ([#4555](https://github.com/sveltejs/svelte/issues/4555))
* Fix contextual dynamic `bind:this` inside `{#each}` block ([#4686](https://github.com/sveltejs/svelte/issues/4686))
* Do not display a11y warning about missing `href` for `<a>` with `name` or `id` ([#4697](https://github.com/sveltejs/svelte/issues/4697))
* Disable infinite loop guard inside generators ([#4698](https://github.com/sveltejs/svelte/issues/4698))
* Display `a11y-invalid-attribute` warning for `href="javascript:..."` ([#4733](https://github.com/sveltejs/svelte/pull/4733))
* Implement `a11y-img-redundant-alt` warning ([#4750](https://github.com/sveltejs/svelte/pull/4750))
* Fix variable name conflict with component called `<Anchor>` ([#4768](https://github.com/sveltejs/svelte/issues/4768))
## 3.21.0
* Support dimension bindings in cross-origin environments ([#2147](https://github.com/sveltejs/svelte/issues/2147))
* Fix several related outro bugs ([#3202](https://github.com/sveltejs/svelte/issues/3202), [#3410](https://github.com/sveltejs/svelte/issues/3410), [#3685](https://github.com/sveltejs/svelte/issues/3685), [#4620](https://github.com/sveltejs/svelte/issues/4620), [#4630](https://github.com/sveltejs/svelte/issues/4630))
* Try using `globalThis` rather than `globals` for the benefit of non-Node servers and web workers ([#3561](https://github.com/sveltejs/svelte/issues/3561), [#4545](https://github.com/sveltejs/svelte/issues/4545))
* Support `{#await ... catch ...}` syntax shorthand ([#3623](https://github.com/sveltejs/svelte/issues/3623))
* Fix attaching of JS debugging comments to HTML comments ([#4565](https://github.com/sveltejs/svelte/issues/4565))
* Fix `<svelte:component/>` within `<slot/>` ([#4597](https://github.com/sveltejs/svelte/issues/4597))
* Fix bug with updating simple `{#if}` blocks ([#4629](https://github.com/sveltejs/svelte/issues/4629))
* Fix issues with `<input type="number">` updates ([#4631](https://github.com/sveltejs/svelte/issues/4631), [#4687](https://github.com/sveltejs/svelte/issues/4687))
* Prevent illegal attribute names ([#4648](https://github.com/sveltejs/svelte/issues/4648))
* Fix `{#if}` block directly within `<slot/>` ([#4703](https://github.com/sveltejs/svelte/issues/4703))
## 3.20.1
* Fix compiler regression with slots ([#4562](https://github.com/sveltejs/svelte/issues/4562))
## 3.20.0
* Allow destructuring in `{#await}` blocks ([#1851](https://github.com/sveltejs/svelte/issues/1851))
* Allow `<svelte:self>` to be used in a slot ([#2798](https://github.com/sveltejs/svelte/issues/2798))
* Expose object of unknown props in `$$restProps` ([#2930](https://github.com/sveltejs/svelte/issues/2930))
* Prevent passing named slots other than from the top level within a component ([#3385](https://github.com/sveltejs/svelte/issues/3385))
* Allow transitions and animations to work within iframes ([#3624](https://github.com/sveltejs/svelte/issues/3624))
* Fix initialising slot fallbacks when unnecessary ([#3763](https://github.com/sveltejs/svelte/issues/3763))
* Disallow binding directly to `const` variables ([#4479](https://github.com/sveltejs/svelte/issues/4479))
* Fix re-attaching event handlers on keyed `{#each}` blocks ([#4491](https://github.com/sveltejs/svelte/issues/4491))
* Fix updating keyed `{#each}` blocks with `{:else}` ([#4536](https://github.com/sveltejs/svelte/issues/4536), [#4549](https://github.com/sveltejs/svelte/issues/4549))
* Fix hydration of top-level content ([#4542](https://github.com/sveltejs/svelte/issues/4542))
## 3.19.2
* In `dev` mode, display a runtime warning when a component is passed an unexpected slot ([#1020](https://github.com/sveltejs/svelte/issues/1020), [#1447](https://github.com/sveltejs/svelte/issues/1447))
* In `vars` array, correctly indicate whether `module` variables are `mutated` or `reassigned` ([#3215](https://github.com/sveltejs/svelte/issues/3215))
* Fix spread props not updating in certain situations ([#3521](https://github.com/sveltejs/svelte/issues/3521), [#4480](https://github.com/sveltejs/svelte/issues/4480))
* Use the fallback content for slots if they are passed only whitespace ([#4092](https://github.com/sveltejs/svelte/issues/4092))
* Fix bitmask overflow for `{#if}` blocks ([#4263](https://github.com/sveltejs/svelte/issues/4263))
* In `dev` mode, check for unknown props even if the component has no writable props ([#4323](https://github.com/sveltejs/svelte/issues/4323))
* Exclude global variables from `$capture_state` ([#4463](https://github.com/sveltejs/svelte/issues/4463))
* Fix bitmask overflow for slots ([#4481](https://github.com/sveltejs/svelte/issues/4481))
## 3.19.1
* Do not treat modifications to `$$props` as updates to a store called `$props` ([#4368](https://github.com/sveltejs/svelte/issues/4368))
* Deconflict `value` parameter name used in contextual bindings ([#4445](https://github.com/sveltejs/svelte/issues/4445))
* Fix dev mode validation of `{#each}` blocks using strings ([#4450](https://github.com/sveltejs/svelte/issues/4450))
## 3.19.0
* Fix indirect bindings involving elements with spreads ([#3680](https://github.com/sveltejs/svelte/issues/3680))
* `$capture_state`/`$inject_state` now act on the component's entire state, rather than its props ([#3822](https://github.com/sveltejs/svelte/pull/3822))
* Warn when using `<Foo/>` and `Foo` is dynamic ([#4331](https://github.com/sveltejs/svelte/issues/4331))
* Display compilation warnings in `svelte/register` in dev mode ([#4364](https://github.com/sveltejs/svelte/issues/4364))
* Fix unneeded updating of keyed each blocks ([#4373](https://github.com/sveltejs/svelte/issues/4373))
* Throw runtime error in dev mode for non-array-like values in `{#each}` blocks ([#4408](https://github.com/sveltejs/svelte/issues/4408))
## 3.18.2
* Fix binding to module-level variables ([#4086](https://github.com/sveltejs/svelte/issues/4086))
* Improve parsing error messages when there is a pending unclosed tag ([#4131](https://github.com/sveltejs/svelte/issues/4131))
* Disallow attribute/prop names from matching two-way-bound names or `{shorthand}` attribute/prop names ([#4325](https://github.com/sveltejs/svelte/issues/4325))
* Improve performance of `flush()` by not using `.shift()` ([#4356](https://github.com/sveltejs/svelte/pull/4356))
* Permit reserved keywords as destructuring keys in `{#each}` ([#4372](https://github.com/sveltejs/svelte/issues/4372))
* Disallow reserved keywords in `{expressions}` ([#4372](https://github.com/sveltejs/svelte/issues/4372))
* Fix code generation error with precedence of arrow functions ([#4384](https://github.com/sveltejs/svelte/issues/4384))
* Fix event handlers that are dynamic via reactive declarations or stores ([#4388](https://github.com/sveltejs/svelte/issues/4388))
* Fix invalidation in expressions like `++foo.bar` ([#4393](https://github.com/sveltejs/svelte/issues/4393))
## 3.18.1
* Fix code generation error with adjacent inline and block comments ([#4312](https://github.com/sveltejs/svelte/issues/4312))
* Fix detection of unused CSS selectors that begin with a `:global()` but contain a scoped portion ([#4314](https://github.com/sveltejs/svelte/issues/4314))
## 3.18.0
* Fix infinite loop when instantiating another component during `onMount` ([#3218](https://github.com/sveltejs/svelte/issues/3218))
* Make autosubscribing to a nullish store a no-op ([#2181](https://github.com/sveltejs/svelte/issues/2181))
## 3.17.3
* Fix updating a `<slot>` inside an `{#if}` or other block ([#4292](https://github.com/sveltejs/svelte/issues/4292))
* Fix using RxJS observables in `derived` stores ([#4298](https://github.com/sveltejs/svelte/issues/4298))
* Add dev mode check to disallow duplicate keys in a keyed `{#each}` ([#4301](https://github.com/sveltejs/svelte/issues/4301))
* Fix hydration of `<title>` when starting from SSR-generated code with `hydratable: true` ([#4310](https://github.com/sveltejs/svelte/issues/4310))
## 3.17.2
* Fix removing attributes during hydration ([#1733](https://github.com/sveltejs/svelte/issues/1733))
* Disallow two-way binding to a variable declared by an `{#await}` block ([#4012](https://github.com/sveltejs/svelte/issues/4012))
* Allow access to `let:` variables in sibling attributes on slot root ([#4173](https://github.com/sveltejs/svelte/issues/4173))
* Fix `~=` and class selector matching against values separated by any whitespace characters ([#4242](https://github.com/sveltejs/svelte/issues/4242))
* Fix code generation for `await`ed expressions that need parentheses ([#4267](https://github.com/sveltejs/svelte/issues/4267))
* Preserve JavaScript comments from the original component source where possible ([#4268](https://github.com/sveltejs/svelte/issues/4268))
* Add some more known globals ([#4276](https://github.com/sveltejs/svelte/pull/4276))
* Correctly apply event modifiers to `<svelte:body>` events ([#4278](https://github.com/sveltejs/svelte/issues/4278))
## 3.17.1
* Only attach SSR mode markers to a component's `<head>` elements when compiling with `hydratable: true` ([#4258](https://github.com/sveltejs/svelte/issues/4258))
## 3.17.0
* Remove old `<head>` elements during hydration so they aren't duplicated ([#1607](https://github.com/sveltejs/svelte/issues/1607))
* Prevent text input cursor jumping in Safari with one-way binding ([#3449](https://github.com/sveltejs/svelte/issues/3449))
* Expose compiler version in dev events ([#4047](https://github.com/sveltejs/svelte/issues/4047))
* Don't run actions before their element is in the document ([#4166](https://github.com/sveltejs/svelte/issues/4166))
* Fix reactive assignments with destructuring and stores where the destructured value should be undefined ([#4170](https://github.com/sveltejs/svelte/issues/4170))
* Fix hydrating `{:else}` in `{#each}` ([#4202](https://github.com/sveltejs/svelte/issues/4202))
* Do not automatically declare variables in reactive declarations when assigning to a member expression ([#4212](https://github.com/sveltejs/svelte/issues/4212))
* Fix stringifying of attributes in SSR mode when there are spread attributes ([#4240](https://github.com/sveltejs/svelte/issues/4240))
* Only render one `<title>` in SSR mode when multiple components provide one ([#4250](https://github.com/sveltejs/svelte/pull/4250))
## 3.16.7
* Also apply actions in the order they're given along with other directives ([#2446](https://github.com/sveltejs/svelte/issues/2446), [#4156](https://github.com/sveltejs/svelte/pull/4156))
* Check whether a dynamic event handler is a function before calling it ([#4090](https://github.com/sveltejs/svelte/issues/4090))
* Correctly mark event handlers as dynamic when they involve an expression used in a `bind:` elsewhere ([#4155](https://github.com/sveltejs/svelte/pull/4155))
## 3.16.6
* Fix CSS specificity bug when encapsulating styles ([#1277](https://github.com/sveltejs/svelte/issues/1277))
* Apply directives in the order they're given ([#2446](https://github.com/sveltejs/svelte/issues/2446))
* Fix destructuring in `let:` directives ([#2751](https://github.com/sveltejs/svelte/issues/2751))
* Preserve whitespace around `<tspan>`s in `<svg>`s ([#3998](https://github.com/sveltejs/svelte/issues/3998))
## 3.16.5
* Better fix for cascading invalidations and fix some regressions ([#4098](https://github.com/sveltejs/svelte/issues/4098), [#4114](https://github.com/sveltejs/svelte/issues/4114), [#4120](https://github.com/sveltejs/svelte/issues/4120))
## 3.16.4
* Fix slots with props not propagating through to inner slots ([#4061](https://github.com/sveltejs/svelte/issues/4061))
* Fix noting autosubscribed stores as `referenced` in `vars` for tooling ([#4081](https://github.com/sveltejs/svelte/issues/4081))
* Fix cascading invalidations in certain situations ([#4094](https://github.com/sveltejs/svelte/issues/4094))
## 3.16.3
* Fix bitmask overflow when using slotted components ([#4077](https://github.com/sveltejs/svelte/issues/4077))
* Remove unnecessary `$$invalidate` calls from init block ([#4018](https://github.com/sveltejs/svelte/issues/4018))
## 3.16.2
* Handle slot updates when parent component has a bitmask overflow ([#4078](https://github.com/sveltejs/svelte/pull/4078))
## 3.16.1
* Fix unused export warning for props used as stores ([#4021](https://github.com/sveltejs/svelte/issues/4021))
* Fix `{:then}` without resolved value containing `{#each}` ([#4022](https://github.com/sveltejs/svelte/issues/4022))
* Fix incorrect code generated with `loopGuardTimeout` ([#4034](https://github.com/sveltejs/svelte/issues/4034))
* Fix handling of bitmask overflow and globals ([#4037](https://github.com/sveltejs/svelte/issues/4037))
* Fix `{:then}` containing `{#if}` ([#4044](https://github.com/sveltejs/svelte/issues/4044))
* Fix bare `import`s in `format: 'cjs'` output mode ([#4055](https://github.com/sveltejs/svelte/issues/4050))
* Warn when using a known global as a component name ([#4070](https://github.com/sveltejs/svelte/issues/4070))
## 3.16.0
* Use bitmasks to track changes ([#3945](https://github.com/sveltejs/svelte/pull/3945))
* Fix heisenbug with component styles ([#3977](https://github.com/sveltejs/svelte/issues/3977))
* Do not warn about missing expected props for `export function foo() {}` ([#3954](https://github.com/sveltejs/svelte/issues/3954))
* Fix `context="module"` exports with the same name as an instance variable ([#3983](https://github.com/sveltejs/svelte/issues/3983))
* Fix binding to contextual values from `{#each}` blocks referring to global variables ([#3992](https://github.com/sveltejs/svelte/issues/3992))
* Use `requestAnimationFrame` callback argument for smoother transitions ([#4014](https://github.com/sveltejs/svelte/pull/4014))
* Fix `listen_dev` argument order ([#4016](https://github.com/sveltejs/svelte/pull/4016))
## 3.15.0
* Hide commented sections from preprocessors ([#3894](https://github.com/sveltejs/svelte/pull/3894))
* Add `seeking` and `ended` bindings to media elements ([#3650](https://github.com/sveltejs/svelte/pull/3650))
* Add `videoWidth` and `videoHeight` bindings to video elements ([#3927](https://github.com/sveltejs/svelte/pull/3927))
* Fix for dynamic event handlers ([#3934](https://github.com/sveltejs/svelte/pull/3934))
* Handle scale transforms when using the `flip` animation ([#3555](https://github.com/sveltejs/svelte/issues/3555))
* Fix some code generation bugs ([#3929](https://github.com/sveltejs/svelte/issues/3929), [#3939](https://github.com/sveltejs/svelte/issues/3939))
* Add `aria-hidden="true"` to objects generated when adding resize-listeners, to improve accessibility ([#3948](https://github.com/sveltejs/svelte/issues/3948))
## 3.14.1
* Deconflict block method names with other variables ([#3900](https://github.com/sveltejs/svelte/issues/3900))
* Fix entity encoding issue in text nodes with constant expressions ([#3911](https://github.com/sveltejs/svelte/issues/3911))
* Make code for unknown prop warnings compatible with older js engines ([#3914](https://github.com/sveltejs/svelte/issues/3914))
## 3.14.0
* Add `loopGuardTimeout` option that augments `for`/`while` loops to prevent infinite loops, primarily for use in the REPL ([#3887](https://github.com/sveltejs/svelte/pull/3887))
* Keep component bindings in sync when changed in reactive statements ([#3382](https://github.com/sveltejs/svelte/issues/3382))
* Update attributes before bindings ([#3857](https://github.com/sveltejs/svelte/issues/3857))
* Prevent variable naming conflict ([#3899](https://github.com/sveltejs/svelte/issues/3899))
## 3.13.0
* New structured code generation, which eliminates a number of edge cases and obscure bugs ([#3539](https://github.com/sveltejs/svelte/pull/3539))
@ -229,7 +1078,7 @@ Also:
## 3.5.1
* Accommodate webpack idiosyncracies
* Accommodate webpack idiosyncrasies
## 3.5.0
@ -431,7 +1280,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))
@ -1441,7 +2290,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

@ -2,7 +2,7 @@
Svelte is a new way to build web applications. It's a compiler that takes your declarative components and converts them into efficient JavaScript that surgically updates the DOM.
The [Open Source Guides](https://opensource.guide/) website has a collection of resources for individuals, communities, and companies who want to learn how to run and contribute to an open source project. Contributors and people new to open source alike will find the following guides especially useful:
The [Open Source Guides](https://opensource.guide/) website has a collection of resources for individuals, communities, and companies. These resources help people who want to learn how to run and contribute to open source projects. Contributors and people new to open source alike will find the following guides especially useful:
* [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/)
* [Building Welcoming Communities](https://opensource.guide/building-community/)
@ -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,77 +24,108 @@ 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.
## Our process
### RFCs
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.
### Roadmap
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.
### Maintainer meetings
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.
### Prioritization
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.
## Bugs
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 a are certain this is a new, unreported bug, you can submit a [bug report](#reporting-new-issues).
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).
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 see anything you'd like to be implemented, create a [feature request issue](https://github.com/sveltejs/svelte/issues/new?template=feature_request.md)
## Reporting new issues
### Reporting new issues
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.
## Installation
## 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.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.
Small pull requests are much easier to review and more likely to get merged.
### Installation
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`.
### Creating a branch
## Pull requests
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).
### Your first pull request
### Testing
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.
A good test plan has the exact commands you ran and their output, provides screenshots or videos if the pull request changes UI.
Working on your first Pull Request? You can learn how from this free video series:
- If you've changed APIs, update the documentation.
[**How to Contribute to an Open Source Project on GitHub**](https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github)
#### Writing tests
### Proposing a change
All tests are located in `/test` folder.
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).
Test samples are kept in `/test/xxx/samples` folder.
If you're only fixing a bug, it's fine to submit a pull request right away but we still recommend to 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.
#### Running tests
### Sending a pull request
1. To run test, run `npm run test`.
1. To run test for a specific feature, you can use the `-g` (aka `--grep`) option. For example, to only run test involving transitions, run `npm run test -- -g transition`.
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.
##### Running solo test
Please make sure the following is done when submitting a pull request:
1. To run only one test, rename the test sample folder to end with `.solo`. For example, to run the `test/js/samples/action` only, rename it to `test/js/samples/action.solo`.
1. To run only one test suite, rename the test suite folder to end with `.solo`. For example, to run the `test/js` test suite only, rename it to `test/js.solo`.
1. Remember to rename the test folder back. The CI will fail if there's a solo test.
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`).
##### Updating `.expected` files
All pull requests should be opened against the `master` branch.
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`)
#### Test plan
### Style guide
A good test plan has the exact commands you ran and their output, provides screenshots or videos if the pull request changes UI.
[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`.
- If you've changed APIs, update the documentation.
#### Code conventions
#### Writing tests
- `snake_case` for internal variable names and methods.
- `camelCase` for public variable names and methods.
All tests are located in `/test` folder.
### Sending your pull request
Test samples are kept in `/test/xxx/samples` folder.
Please make sure the following is done when submitting a pull request:
#### Running tests
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`).
1. To run test, run `npm run test`
1. To run test for a specific feature, you can use the `-g` (aka `--grep`) option. For example, to only run test involving transitions, run `npm run test -- -g transition`.
All pull requests should be opened against the `master` branch. Make sure the PR does only one thing, otherwise please split it.
#### Breaking changes
@ -109,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-19 [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,25 +1,7 @@
<p>
<a href="https://svelte.dev">
<img alt="Cybernetically enhanced web apps: Svelte" src="https://sveltejs.github.io/assets/banner.png">
</a>
[![Cybernetically enhanced web apps: Svelte](https://sveltejs.github.io/assets/banner.png)](https://svelte.dev)
<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://packagephobia.now.sh/result?p=svelte">
<img src="https://packagephobia.now.sh/badge?p=svelte" alt="install size">
</a>
<a href="https://travis-ci.org/sveltejs/svelte">
<img src="https://api.travis-ci.org/sveltejs/svelte.svg?branch=master"
alt="build status">
</a>
<a href="https://github.com/sveltejs/svelte/blob/master/LICENSE">
<img src="https://img.shields.io/npm/l/svelte.svg" alt="license">
</a>
</p>
[![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?
@ -29,6 +11,20 @@ Svelte is a new way to build web applications. It's a compiler that takes your d
Learn more at the [Svelte website](https://svelte.dev), or stop by the [Discord chatroom](https://svelte.dev/chat).
## Supporting Svelte
Svelte is an MIT-licensed open source project with its ongoing development made possible entirely by fantastic volunteers. If you'd like to support their efforts, please consider:
- [Becoming a backer on Open Collective](https://opencollective.com/svelte).
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!
@ -41,12 +37,9 @@ cd svelte
npm install
```
> Many tests depend on newlines being preserved as `<LF>`. On Windows, you can ensure this by cloning with:
> ```bash
> git -c core.autocrlf=false clone https://github.com/sveltejs/svelte.git
> ```
> Do not use Yarn to install the dependencies, as the specific package versions in `package-lock.json` are used to build and test Svelte.
To build the compiler, and all the other modules included in the package:
To build the compiler and all the other modules included in the package:
```bash
npm run build
@ -58,7 +51,7 @@ To watch for changes and continually rebuild the package (this is useful if you'
npm run dev
```
The compiler is written in [TypeScript](https://www.typescriptlang.org/), but don't let that put you off — it's basically just JavaScript with type annotations. You'll pick it up in no time. If you're using an editor other than [Visual Studio Code](https://code.visualstudio.com/) you may need to install a plugin in order to get syntax highlighting and code hints etc.
The compiler is written in [TypeScript](https://www.typescriptlang.org/), but don't let that put you off — it's basically just JavaScript with type annotations. You'll pick it up in no time. If you're using an editor other than [Visual Studio Code](https://code.visualstudio.com/), you may need to install a plugin in order to get syntax highlighting and code hints, etc.
### Running Tests
@ -76,15 +69,12 @@ 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). To develop locally:
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).
```bash
cd site
npm install && npm run update
npm run dev
```
### Is svelte.dev down?
Probably not, but it's possible. If you can't seem to access any `.dev` sites, check out [this SuperUser question and answer](https://superuser.com/q/1413402).
## License
[MIT](LICENSE)
[MIT](LICENSE.md)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

@ -0,0 +1,4 @@
if (!process.env.PUBLISH) {
console.error('npm publish must be run with the PUBLISH environment variable set');
process.exit(1);
}

1588
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,28 @@
// This script generates the TypeScript definitions
const { execSync } = require('child_process');
const { readFileSync, writeFileSync } = require('fs');
try {
execSync('tsc -p src/compiler --emitDeclarationOnly && tsc -p src/runtime --emitDeclarationOnly');
} catch (err) {
console.error(err.stderr.toString());
throw err;
}
// 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"'
);

@ -1,4 +0,0 @@
--require source-map-support/register
--full-trace
--recursive
test/test.js

@ -1 +0,0 @@
test/test.js

9156
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -1,6 +1,6 @@
{
"name": "svelte",
"version": "3.13.0",
"version": "3.55.1",
"description": "Cybernetically enhanced web apps",
"module": "index.mjs",
"main": "index",
@ -9,35 +9,98 @@
"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"
},
"./register": {
"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": {
"node": ">= 8"
},
"types": "types/runtime/index.d.ts",
"scripts": {
"test": "mocha --opts mocha.opts",
"test:unit": "mocha --require sucrase/register --recursive src/**/__test__.ts",
"quicktest": "mocha --opts mocha.opts",
"precoverage": "c8 mocha --opts mocha.coverage.opts",
"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": "npm run lint && PUBLISH=true 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",
@ -54,50 +117,47 @@
"bugs": {
"url": "https://github.com/sveltejs/svelte/issues"
},
"homepage": "https://github.com/sveltejs/svelte#README",
"homepage": "https://svelte.dev",
"devDependencies": {
"@rollup/plugin-replace": "^2.2.1",
"@types/mocha": "^5.2.7",
"@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": "^11.2.1",
"@rollup/plugin-replace": "^2.3.0",
"@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.8.0",
"@types/aria-query": "^5.0.0",
"@types/mocha": "^7.0.0",
"@types/node": "^8.10.53",
"@typescript-eslint/eslint-plugin": "^1.13.0",
"@typescript-eslint/parser": "^2.1.0",
"acorn": "^7.1.0",
"agadoo": "^1.1.0",
"c8": "^5.0.1",
"code-red": "0.0.19",
"codecov": "^3.5.0",
"css-tree": "1.0.0-alpha22",
"eslint": "^6.3.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-svelte3": "^2.7.3",
"estree-walker": "^0.8.1",
"is-reference": "^1.1.4",
"jsdom": "^15.1.1",
"kleur": "^3.0.3",
"@typescript-eslint/eslint-plugin": "^5.22.0",
"@typescript-eslint/parser": "^5.22.0",
"acorn": "^8.8.1",
"agadoo": "^2.0.0",
"aria-query": "^5.1.1",
"axobject-query": "^3.1.1",
"code-red": "^0.2.5",
"css-tree": "^2.2.1",
"eslint": "^8.26.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-svelte3": "^4.0.0",
"estree-walker": "^3.0.1",
"is-reference": "^3.0.0",
"jsdom": "^15.2.1",
"kleur": "^4.1.5",
"locate-character": "^2.0.5",
"magic-string": "^0.25.3",
"mocha": "^6.2.0",
"periscopic": "^2.0.0",
"puppeteer": "^1.19.0",
"rollup": "^1.21.4",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-json": "^4.0.0",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-sucrase": "^2.1.0",
"rollup-plugin-typescript": "^1.0.1",
"rollup-plugin-virtual": "^1.0.1",
"source-map": "^0.7.3",
"source-map-support": "^0.5.13",
"tiny-glob": "^0.2.6",
"tslib": "^1.10.0",
"typescript": "^3.5.3"
},
"nyc": {
"include": [
"compiler/svelte.js",
"shared.js"
],
"sourceMap": true,
"instrument": true
"mocha": "^7.0.0",
"periscopic": "^3.0.4",
"puppeteer": "^2.0.0",
"rollup": "^1.27.14",
"source-map": "^0.7.4",
"source-map-support": "^0.5.21",
"tiny-glob": "^0.2.9",
"tslib": "^2.4.1",
"typescript": "^3.7.5",
"util": "^0.12.5"
}
}

@ -36,7 +36,15 @@ function registerExtension(extension) {
format: 'cjs'
});
const { js } = compile(fs.readFileSync(filename, 'utf-8'), options);
const { js, warnings } = compile(fs.readFileSync(filename, 'utf-8'), options);
if (options.dev) {
warnings.forEach(warning => {
console.warn(`\nSvelte Warning in ${warning.filename}:`);
console.warn(warning.message);
console.warn(warning.frame);
})
}
return module._compile(js.code, filename);
};

@ -1,10 +1,10 @@
import fs from 'fs';
import replace from '@rollup/plugin-replace';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import json from 'rollup-plugin-json';
import sucrase from 'rollup-plugin-sucrase';
import typescript from 'rollup-plugin-typescript';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import json from '@rollup/plugin-json';
import sucrase from '@rollup/plugin-sucrase';
import typescript from '@rollup/plugin-typescript';
import pkg from './package.json';
const is_publish = !!process.env.PUBLISH;
@ -20,7 +20,7 @@ const ts_plugin = is_publish
const external = id => id.startsWith('svelte/');
fs.writeFileSync(`./compiler.d.ts`, `export { compile, parse, preprocess, VERSION } from './types/compiler/index';`);
fs.writeFileSync(`./compiler.d.ts`, `export { compile, parse, preprocess, walk, VERSION } from './types/compiler/index';`);
export default [
/* runtime */
@ -30,12 +30,30 @@ export default [
{
file: `index.mjs`,
format: 'esm',
paths: id => id.startsWith('svelte/') && `${id.replace('svelte', '.')}`
paths: id => id.startsWith('svelte/') && `${id.replace('svelte', '.')}/index.mjs`
},
{
file: `index.js`,
format: 'cjs',
paths: id => id.startsWith('svelte/') && `${id.replace('svelte', '.')}`
paths: id => id.startsWith('svelte/') && `${id.replace('svelte', '.')}/index.js`
}
],
external,
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,
@ -50,16 +68,19 @@ export default [
{
file: `${dir}/index.mjs`,
format: 'esm',
paths: id => id.startsWith('svelte/') && `${id.replace('svelte', '..')}`
paths: id => id.startsWith('svelte/') && `${id.replace('svelte', '..')}/index.mjs`
},
{
file: `${dir}/index.js`,
format: 'cjs',
paths: id => id.startsWith('svelte/') && `${id.replace('svelte', '..')}`
paths: id => id.startsWith('svelte/') && `${id.replace('svelte', '..')}/index.js`
}
],
external,
plugins: [
replace({
__VERSION__: pkg.version
}),
ts_plugin,
{
writeBundle(bundle) {
@ -87,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/**']
@ -96,12 +127,20 @@ export default [
json(),
ts_plugin
],
output: {
file: 'compiler.js',
format: is_publish ? 'umd' : 'cjs',
name: 'svelte',
sourcemap: true,
},
output: [
{
file: 'compiler.js',
format: is_publish ? 'umd' : 'cjs',
name: 'svelte',
sourcemap: true,
},
{
file: 'compiler.mjs',
format: 'esm',
name: 'svelte',
sourcemap: true,
}
],
external: is_publish
? []
: id => id === 'acorn' || id === 'magic-string' || id.startsWith('css-tree')

@ -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,19 +0,0 @@
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 sapper
docker:
@echo "\n~> building docker image"
@gcloud builds submit -t $(IMAGE)
deploy: sapper docker
@echo "\n~> deploying $(SERVICE) to Cloud Run servers"
@gcloud beta run deploy $(SERVICE) --allow-unauthenticated --platform managed --region us-central1 --image $(IMAGE) --memory=512Mi

@ -1,50 +0,0 @@
## Running locally
Set up the project:
```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
```
Start the server with `npm run dev`, and navigate to [localhost:3000](http://localhost:3000).
## Using a 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.
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 sapper`. The output can be found in `__sapper__/build`.
## Testing
Tests can be run using `npm run test`.
## 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,18 +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 cypress
- 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](http://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,60 +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
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.
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 [Now](https://zeit.co/now) 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.technology), 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.technology/docs#why-the-name-">name comes from</a> the term for combat engineers, and is also short for Svelte app maker</p></aside>
[Sapper](https://sapper.svelte.technology) is the answer to that question. **Sapper is a Next.js-style framework that aims to meet the eleven criteria at the top of this article while dramatically reducing the amount of code that gets sent to the browser.** It's implemented as Express-compatible middleware, meaning it's easy to understand and customise.
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](http://svelte-realworld.now.sh/) 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 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,69 +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
To 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
To treat `*.svelte` files as HTML, add the following lines to your `settings.json` file:
```cson
"files.associations": {
"*.svelte": "html"
}
```
## JetBrains WebStorm
To treat `*.svelte` files as HTML in WebStorm, you need to create a new file type association. Please refer to the [JetBrains website](https://www.jetbrains.com/help/webstorm/creating-and-registering-file-types.html) to see how.
## Sublime Text 3
Open any `.svelte` file.
Go to *__View → Syntax → Open all with current extension as... → HTML__*.

@ -1,9 +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
draft: true
---
*Coming soon* This blog post will walk you through installing Node.js and git and using Terminal.app to clone a project template and start developing with Svelte

@ -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](https://svelte.dev/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.

@ -2,8 +2,10 @@
title: Before we begin
---
> Temporary note: This document is a work-in-progress. Please forgive any missing or misleading parts, and don't be shy about asking for help in the [Discord chatroom](chat). The [tutorial](tutorial) is more complete; start there.
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](https://svelte.dev/chat).
Using an older version of Svelte? Have a look at the [v2 docs](https://v2.svelte.dev).

@ -1,258 +0,0 @@
---
title: Component format
---
---
Components are the building blocks of Svelte applications. They are written into `.svelte` files, using a superset of HTML.
All three sections — script, styles and markup — are optional.
```html
<script>
// logic goes here
</script>
<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
---
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).
```html
<script>
export let foo;
// Values that are passed in as props
// are immediately available
console.log({ foo });
</script>
```
---
You can specify a default value, which will be used if the component's consumer doesn't specify a prop.
In development mode (see the [compiler options](docs#svelte_compile)), a warning will be printed if no default is provided and the consumer does not specify a value. To squelch this warning, ensure that a default is specified, even if it is `undefined`.
```html
<script>
export let bar = 'optional default value';
export let baz = undefined;
</script>
```
---
If you export a `const`, `class` or `function`, it is readonly from outside the component. Function *expressions* are valid props, however.
```html
<script>
// these are readonly
export const thisIs = 'readonly';
export function greet(name) {
alert(`hello ${name}!`);
}
// this is a prop
export let format = n => n.toFixed(2);
</script>
```
---
You can use reserved words as prop names.
```html
<script>
let className;
// creates a `class` property, even
// though it is a reserved word
export { className as class };
</script>
```
##### 2. Assignments are 'reactive'
---
To change component state and trigger a re-render, just assign to a locally declared variable.
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).
```html
<script>
let count = 0;
function handleClick () {
// calling this function will trigger an
// update if the markup references `count`
count = count + 1;
}
</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 immediately before the component updates, whenever the values that they depend on have changed.
```html
<script>
export let title;
// this will update `document.title` whenever
// the `title` prop changes
$: document.title = title;
$: {
console.log(`multiple statements can be combined`);
console.log(`the current title is ${title}`);
}
</script>
```
---
If a statement consists entirely of an assignment to an undeclared variable, Svelte will inject a `let` declaration on your behalf.
```html
<script>
export let num;
// we don't need to declare `squared` and `cubed`
// — Svelte does it for us
$: squared = num * num;
$: cubed = squared * num;
</script>
```
##### 4. Prefix stores with `$` to access their values
---
A *store* is any 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. You can use these as the basis for your own stores, or you can implement your stores from scratch.
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. The `.subscribe` method must also return an unsubscription function. Calling an unsubscription function must stop its subscription, and its corresponding subscription function must not be called again by the store.
A store may optionally contain a `.set` method, which must accept as its argument a new value for the store, and which synchronously calls all of the store's active subscription functions. Such a store is called a *writable store*.
```js
const unsubscribe = store.subscribe(value => {
console.log(value);
}); // logs `value`
// later...
unsubscribe();
```
---
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.
Assignments to `$`-prefixed variables require that the variable be a writable store, and will result in a call to the store's `.set` method.
Note that the store must be declared at the top level of the component — not inside an `if` block or a function, for example.
Local variables (that do not represent store values) must *not* have a `$` prefix.
```html
<script>
import { writable } from 'svelte/store';
const count = writable(0);
console.log($count); // logs 0
count.set(1);
console.log($count); // logs 1
$count = 2;
console.log($count); // logs 2
</script>
```
### &lt;script context="module"&gt;
---
A `<script>` tag with a `context="module"` attribute runs once when the module first evaluates, rather than for each component instance. Values declared in this block are accessible from a regular `<script>` (and the component markup) but not vice versa.
You can `export` bindings from this block, and they will become exports of the compiled module.
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](https://svelte.dev/docs#svelte_store).
```html
<script context="module">
let totalComponents = 0;
// this allows an importer to do e.g.
// `import Example, { alertTotal } from './Example.svelte'`
export function alertTotal() {
alert(totalComponents);
}
</script>
<script>
totalComponents += 1;
console.log(`total number of times this component has been created: ${totalComponents}`);
</script>
```
### &lt;style&gt;
---
CSS inside a `<style>` block will be scoped to that component.
This works by adding a class to affected elements, which is based on a hash of the component styles (e.g. `svelte-123xyz`).
```html
<style>
p {
/* this will only affect <p> elements in this component */
color: burlywood;
}
</style>
```
---
To apply styles to a selector globally, use the `:global(...)` modifier.
```html
<style>
:global(body) {
/* this will apply to <body> */
margin: 0;
}
div :global(strong) {
/* this will apply to all <strong> elements, in any
component, that are inside <div> elements belonging
to this component */
color: goldenrod;
}
</style>
```

@ -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).

@ -0,0 +1,379 @@
---
title: Component format
---
---
Components are the building blocks of Svelte applications. They are written into `.svelte` files, using a superset of HTML.
All three sections — script, styles and markup — are optional.
```sv
<script>
// logic goes here
</script>
<!-- markup (zero or more items) goes here -->
<style>
/* styles go here */
</style>
```
### &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
---
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>
export let foo;
// Values that are passed in as props
// are immediately available
console.log({ foo });
</script>
```
---
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#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>
export let bar = 'optional default initial value';
export let baz = undefined;
</script>
```
---
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>
// these are readonly
export const thisIs = 'readonly';
export function greet(name) {
alert(`hello ${name}!`);
}
// this is a prop
export let format = n => n.toFixed(2);
</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.
```sv
<script>
let className;
// creates a `class` property, even
// though it is a reserved word
export { className as class };
</script>
```
#### 2. Assignments are 'reactive'
---
To change component state and trigger a re-render, just assign to a locally declared variable.
Update expressions (`count += 1`) and property assignments (`obj.x = y`) have the same effect.
```sv
<script>
let count = 0;
function handleClick () {
// calling this function will trigger an
// update if the markup references `count`
count = count + 1;
}
</script>
```
---
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>
```
---
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
$: document.title = title;
$: {
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>
```
---
Only values which directly appear within the `$:` block will become dependencies of the reactive statement. For example, in the code below `total` will only update when `x` changes, but not `y`.
```sv
<script>
let x = 0;
let y = 0;
function yPlusAValue(value) {
return value + y;
}
$: total = yPlusAValue(x);
</script>
Total: {total}
<button on:click={() => x++}>
Increment X
</button>
<button on:click={() => y++}>
Increment Y
</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.
```sv
<script>
export let num;
// we don't need to declare `squared` and `cubed`
// — Svelte does it for us
$: squared = num * num;
$: cubed = squared * num;
</script>
```
#### 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#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, 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.
Note that the store must be declared at the top level of the component — not inside an `if` block or a function, for example.
Local variables (that do not represent store values) must *not* have a `$` prefix.
```sv
<script>
import { writable } from 'svelte/store';
const count = writable(0);
console.log($count); // logs 0
count.set(1);
console.log($count); // logs 1
$count = 2;
console.log($count); // logs 2
</script>
```
##### Store contract
```js
store = { subscribe: (subscription: (value: any) => void) => (() => void), set?: (value: any) => void }
```
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.
3. A store may *optionally* contain a `.set` method, which must accept as its argument a new value for the store, and which synchronously calls all of the store's active subscription functions. Such a store is called a *writable store*.
For interoperability with RxJS Observables, the `.subscribe` method is also allowed to return an object with an `.unsubscribe` method, rather than return the unsubscription function directly. Note however that unless `.subscribe` synchronously calls the subscription (which is not required by the Observable spec), Svelte will see the value of the store as `undefined` until it does.
### &lt;script context="module"&gt;
---
A `<script>` tag with a `context="module"` attribute runs once when the module first evaluates, rather than for each component instance. Values declared in this block are accessible from a regular `<script>` (and the component markup) but not vice versa.
You can `export` bindings from this block, and they will become exports of the compiled module.
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#run-time-svelte-store).
```sv
<script context="module">
let totalComponents = 0;
// this allows an importer to do e.g.
// `import Example, { alertTotal } from './Example.svelte'`
export function alertTotal() {
alert(totalComponents);
}
</script>
<script>
totalComponents += 1;
console.log(`total number of times this component has been created: ${totalComponents}`);
</script>
```
### &lt;style&gt;
---
CSS inside a `<style>` block will be scoped to that component.
This works by adding a class to affected elements, which is based on a hash of the component styles (e.g. `svelte-123xyz`).
```sv
<style>
p {
/* this will only affect <p> elements in this component */
color: burlywood;
}
</style>
```
---
To apply styles to a selector globally, use the `:global(...)` modifier.
```sv
<style>
:global(body) {
/* this will apply to <body> */
margin: 0;
}
div :global(strong) {
/* this will apply to all <strong> elements, in any
component, that are inside <div> elements belonging
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>
```
---
If you want to make @keyframes that are accessible globally, you need to prepend your keyframe names with `-global-`.
The `-global-` part will be removed when compiled, and the keyframe then be referenced using just `my-animation-name` elsewhere in your code.
```html
<style>
@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>
```

@ -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,9 +20,9 @@ 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).
```html
```sv
<script>
import { onMount } from 'svelte';
@ -36,7 +36,7 @@ The `onMount` function schedules a callback to run as soon as the component has
If a function is returned from `onMount`, it will be called when the component is unmounted.
```html
```sv
<script>
import { onMount } from 'svelte';
@ -50,6 +50,8 @@ If a function is returned from `onMount`, it will be called when the component i
</script>
```
> This behaviour will only work when the function passed to `onMount` *synchronously* returns a value. `async` functions always return a `Promise`, and as such cannot *synchronously* return a function.
#### `beforeUpdate`
```js
@ -62,7 +64,7 @@ Schedules a callback to run immediately before the component is updated after an
> The first time the callback runs will be before the initial `onMount`
```html
```sv
<script>
import { beforeUpdate } from 'svelte';
@ -82,7 +84,9 @@ afterUpdate(callback: () => void)
Schedules a callback to run immediately after the component has been updated.
```html
> The first time the callback runs will be after the initial `onMount`
```sv
<script>
import { afterUpdate } from 'svelte';
@ -100,11 +104,11 @@ onDestroy(callback: () => void)
---
Schedules a callback to run once the component is unmounted.
Schedules a callback to run immediately before the component is unmounted.
Out of `onMount`, `beforeUpdate`, `afterUpdate` and `onDestroy`, this is the only one that runs inside a server-side component.
```html
```sv
<script>
import { onDestroy } from 'svelte';
@ -124,7 +128,7 @@ promise: Promise = tick()
Returns a promise that resolves once any pending state changes have been applied, or in the next microtask if there are none.
```html
```sv
<script>
import { beforeUpdate, tick } from 'svelte';
@ -144,11 +148,11 @@ 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.
```html
```sv
<script>
import { setContext } from 'svelte';
@ -168,7 +172,7 @@ context: any = getContext(key: any)
Retrieves the context that belongs to the closest parent component with the specified `key`. Must be called during component initialisation.
```html
```sv
<script>
import { getContext } from 'svelte';
@ -176,19 +180,57 @@ Retrieves the context that belongs to the closest parent component with the spec
</script>
```
#### `hasContext`
```js
hasContext: boolean = hasContext(key: any)
```
---
Checks whether a given `key` has been set in the context of a parent component. Must be called during component initialisation.
```sv
<script>
import { hasContext } from 'svelte';
if (hasContext('answer')) {
// do something
}
</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.
```html
```sv
<script>
import { createEventDispatcher } from 'svelte';
@ -202,7 +244,7 @@ Component events created with `createEventDispatcher` create a [CustomEvent](htt
Events dispatched from child components can be listened to in their parent. Any data provided when the event was dispatched is available on the `detail` property of the event object.
```html
```sv
<script>
function callbackFunction(event) {
console.log(`Notify fired! Detail: ${event.detail}`)
@ -212,17 +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 [stores](docs#4_Prefix_stores_with_$_to_access_their_values).
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#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#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)
```
---
@ -268,22 +335,24 @@ 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';
const time = readable(new Date(), set => {
const time = readable(null, set => {
set(new Date());
const interval = setInterval(() => {
set(new Date());
}, 1000);
@ -309,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.
@ -383,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`
@ -397,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.
@ -409,7 +501,7 @@ Both functions return a Promise that resolves when the tween completes. If the t
Out of the box, Svelte will interpolate between two numbers, two arrays or two objects (as long as the arrays and objects are the same 'shape', and their 'leaf' properties are also numbers).
```html
```sv
<script>
import { tweened } from 'svelte/motion';
import { cubicOut } from 'svelte/easing';
@ -448,7 +540,7 @@ $: $size = big ? 100 : 10;
The `interpolate` option allows you to tween between *any* arbitrary values. It must be an `(a, b) => t => value` function, where `a` is the starting value, `b` is the target value, `t` is a number between 0 and 1, and `value` is the result. For example, we can use the [d3-interpolate](https://github.com/d3/d3-interpolate) package to smoothly interpolate between two colours.
```html
```sv
<script>
import { interpolateLab } from 'd3-interpolate';
import { tweened } from 'svelte/motion';
@ -485,17 +577,41 @@ 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
---
As with [`tweened`](#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.
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#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)
```html
```sv
<script>
import { spring } from 'svelte/motion';
@ -517,7 +633,7 @@ $: $size = big ? 100 : 10;
### `svelte/transition`
The `svelte/transition` module exports six functions: `fade`, `fly`, `slide`, `scale`, `draw` and `crossfade`. They are for use with svelte [`transitions`](docs#Transitions).
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`
@ -539,10 +655,11 @@ 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#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).
```html
```sv
<script>
import { fade } from 'svelte/transition';
</script>
@ -574,11 +691,11 @@ 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
```html
```sv
<script>
import { blur } from 'svelte/transition';
</script>
@ -604,20 +721,20 @@ 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)
* `easing` (`function`, default `cubicOut`) — an [easing function](/docs#run-time-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
* `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).
You can see the `fly` transition in action in the [transition tutorial](/tutorial/adding-parameters-to-transitions).
```html
```sv
<script>
import { fly } from 'svelte/transition';
import { quintOut } from 'svelte/easing';
@ -650,17 +767,18 @@ 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
```html
```sv
<script>
import { slide } from 'svelte/transition';
import { quintOut } from 'svelte/easing';
</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}
```
@ -685,11 +803,11 @@ 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
```html
```sv
<script>
import { scale } from 'svelte/transition';
import { quintOut } from 'svelte/easing';
@ -723,11 +841,11 @@ 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.
```html
```sv
<script>
import { draw } from 'svelte/transition';
import { quintOut } from 'svelte/easing';
@ -748,13 +866,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#Animations).
The `svelte/animate` module exports one function for use with Svelte [animations](/docs#template-syntax-element-directives-animate-fn).
#### `flip`
@ -768,20 +914,20 @@ 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`](docs#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)
```html
```sv
<script>
import { flip } from 'svelte/animate';
import { quintOut } from 'svelte/easing';
@ -800,9 +946,9 @@ You can see a full example on the [animations tutorial](tutorial/animate)
### `svelte/easing`
Easing functions specificy 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`.
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 |
@ -872,9 +1018,10 @@ 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
| `hydrate` | `false` | See below
| `intro` | `false` | If `true`, will play transitions on initial render, rather than waiting for subsequent state changes
@ -883,7 +1030,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).
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`.
@ -967,10 +1114,10 @@ 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).
```html
<svelte:options tag="my-element">
```sv
<svelte:options tag="my-element" />
<script>
export let name = 'world';
@ -1004,7 +1151,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>`.
@ -1041,7 +1188,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');
@ -1052,3 +1199,29 @@ const { head, html, css } = App.render({
answer: 42
});
```
---
The `.render()` method accepts the following parameters:
| parameter | default | description |
| --- | --- | --- |
| `props` | `{}` | An object of properties to supply to the component
| `options` | `{}` | An object of options
The `options` object takes in the following options:
| option | default | description |
| --- | --- | --- |
| `context` | `new Map()` | A `Map` of root-level context key-value pairs to supply to the component
```js
const { head, html, css } = App.render(
// props
{ answer: 42 },
// options
{
context: new Map([['context-key', 'context-value']])
}
);
```

@ -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/rollup/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)
* [parcel-plugin-svelte](https://github.com/DeMoorJasper/parcel-plugin-svelte) for users of [Parcel](https://parceljs.org/)
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`
@ -53,6 +51,7 @@ The following options can be passed to the compiler. None are required:
| `tag` | string | null
| `accessors` | boolean | `false`
| `css` | boolean | `true`
| `loopGuardTimeout` | number | 0
| `preserveComments` | boolean | `false`
| `preserveWhitespace` | boolean | `false`
| `outputFilename` | string | `null`
@ -65,20 +64,26 @@ 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`, enables the `hydrate: true` runtime option, which allows a component to upgrade existing DOM rather than creating new DOM from scratch.
| `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.
| `legacy` | `false` | If `true`, generates code that will work in IE9 and IE10, which don't support things like `element.dataset`.
| `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 optimised by Svelte.
| `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.
| `namespace` | `"html"` | The namespace of the element; e.g., `"mathml"`, `"svg"`, `"foreign"`.
---
@ -111,7 +116,8 @@ const {
* `module` is `true` if the value is declared in a `context="module"` script
* `mutated` is `true` if the value's properties are assigned to inside the component
* `reassigned` is `true` if the value is reassigned inside the component
* `referenced` is `true` if the value is used outside the declaration
* `referenced` is `true` if the value is used in the template
* `referenced_from_script` is `true` if the value is used in the `<script>` outside the declaration
* `writable` is `true` if the value was declared with `let` or `var` (but not `const`, `class` or `function`)
* `stats` is an object used by the Svelte developer team for diagnosing the compiler. Avoid relying on it to stay the same!
@ -142,6 +148,7 @@ compiled: {
mutated: boolean,
reassigned: boolean,
referenced: boolean,
referenced_from_script: boolean,
writable: boolean
}>,
stats: {
@ -167,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
@ -179,22 +186,26 @@ const ast = svelte.parse(source, { filename: 'App.svelte' });
### `svelte.preprocess`
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.
```js
result: {
code: string,
dependencies: Array<string>
} = svelte.preprocess(
} = await svelte.preprocess(
source: string,
preprocessors: Array<{
markup?: (input: { content: string, filename: string }) => Promise<{
code: string,
dependencies?: Array<string>
}>,
script?: (input: { content: string, attributes: Record<string, string>, filename: string }) => Promise<{
script?: (input: { content: string, markup: string, attributes: Record<string, string>, filename: string }) => Promise<{
code: string,
dependencies?: Array<string>
}>,
style?: (input: { content: string, attributes: Record<string, string>, filename: string }) => Promise<{
style?: (input: { content: string, markup: string, attributes: Record<string, string>, filename: string }) => Promise<{
code: string,
dependencies?: Array<string>
}>
@ -215,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 } = svelte.preprocess(source, {
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'
@ -233,16 +252,16 @@ const { code } = svelte.preprocess(source, {
---
The `script` and `style` functions receive the contents of `<script>` and `<style>` elements respectively. In addition to `filename`, they get an object of the element's attributes.
The `script` and `style` functions receive the contents of `<script>` and `<style>` elements respectively (`content`) as well as the entire component source text (`markup`). In addition to `filename`, they get an object of the element's attributes.
If a `dependencies` array is returned, it will be included in the result object. This is used by packages like [rollup-plugin-svelte](https://github.com/rollup/rollup-plugin-svelte) to watch additional files for changes, in the case where your `<style>` tag has an `@import` (for example).
If a `dependencies` array is returned, it will be included in the result object. This is used by packages like [rollup-plugin-svelte](https://github.com/sveltejs/rollup-plugin-svelte) to watch additional files for changes, in the case where your `<style>` tag has an `@import` (for example).
```js
const svelte = require('svelte/compiler');
const sass = require('node-sass');
const { dirname } = require('path');
const { code, dependencies } = svelte.preprocess(source, {
const { code, dependencies } = await svelte.preprocess(source, {
style: async ({ content, attributes, filename }) => {
// only process <style lang="sass">
if (attributes.lang !== 'sass') return;
@ -275,7 +294,7 @@ Multiple preprocessors can be used together. The output of the first becomes the
```js
const svelte = require('svelte/compiler');
const { code } = svelte.preprocess(source, [
const { code } = await svelte.preprocess(source, [
{
markup: () => {
console.log('this runs first');

@ -0,0 +1,358 @@
---
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-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,7 +1,7 @@
<script>
let src = 'tutorial/image.gif';
let src = '/tutorial/image.gif';
let name = 'Rick Astley';
</script>
<!-- {src} is short for src={src} -->
<img {src} alt="{name} dancing">
<img {src} alt="{name} dancing">

@ -1,9 +1,9 @@
<p>Styled!</p>
<style>
p {
color: purple;
font-family: 'Comic Sans MS';
font-family: 'Comic Sans MS', cursive;
font-size: 2em;
}
</style>
<p>Styled!</p>
</style>

@ -2,13 +2,13 @@
import Nested from './Nested.svelte';
</script>
<p>These styles...</p>
<Nested/>
<style>
p {
color: purple;
font-family: 'Comic Sans MS';
font-family: 'Comic Sans MS', cursive;
font-size: 2em;
}
</style>
<p>These styles...</p>
<Nested/>
</style>

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

@ -2,11 +2,11 @@
import Thing from './Thing.svelte';
let things = [
{ id: 1, color: '#0d0887' },
{ id: 2, color: '#6a00a8' },
{ id: 3, color: '#b12a90' },
{ id: 4, color: '#e16462' },
{ id: 5, color: '#fca636' }
{ id: 1, color: 'darkblue' },
{ id: 2, color: 'indigo' },
{ id: 3, color: 'deeppink' },
{ id: 4, color: 'salmon' },
{ id: 5, color: 'gold' }
];
function handleClick() {
@ -18,7 +18,7 @@
Remove first thing
</button>
<div style="display: grid; grid-template-columns: 1fr 1fr; grip-gap: 1em">
<div style="display: grid; grid-template-columns: 1fr 1fr; grid-gap: 1em">
<div>
<h2>Keyed</h2>
{#each things as thing (thing.id)}
@ -32,4 +32,4 @@
<Thing current={thing.color}/>
{/each}
</div>
</div>
</div>

@ -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) {
@ -27,4 +27,4 @@
<p>The number is {number}</p>
{:catch error}
<p style="color: red">{error.message}</p>
{/await}
{/await}

@ -7,10 +7,10 @@
}
</script>
<style>
div { width: 100%; height: 100%; }
</style>
<div on:mousemove={handleMousemove}>
The mouse position is {m.x} x {m.y}
</div>
</div>
<style>
div { width: 100%; height: 100%; }
</style>

@ -2,10 +2,10 @@
let m = { x: 0, y: 0 };
</script>
<style>
div { width: 100%; height: 100%; }
</style>
<div on:mousemove="{e => m = { x: e.clientX, y: e.clientY }}">
The mouse position is {m.x} x {m.y}
</div>
</div>
<style>
div { width: 100%; height: 100%; }
</style>

@ -1,9 +1,9 @@
<script>
import FancyButton from './FancyButton.svelte';
import CustomButton from './CustomButton.svelte';
function handleClick() {
alert('clicked');
}
</script>
<FancyButton on:click={handleClick}/>
<CustomButton on:click={handleClick}/>

@ -0,0 +1,22 @@
<button on:click>
Click me
</button>
<style>
button {
height: 4rem;
width: 8rem;
background-color: #aaa;
border-color: #f1c40f;
color: #f1c40f;
font-size: 1.25rem;
background-image: linear-gradient(45deg, #f1c40f 50%, transparent 50%);
background-position: 100%;
background-size: 400%;
transition: background 300ms ease-in-out;
}
button:hover {
background-position: 0;
color: #aaa;
}
</style>

@ -1,15 +0,0 @@
<style>
button {
font-family: 'Comic Sans MS';
font-size: 2em;
padding: 0.5em 1em;
color: royalblue;
background: gold;
border-radius: 1em;
box-shadow: 2px 2px 4px rgba(0,0,0,0.5);
}
</style>
<button on:click>
Click me
</button>

@ -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,12 +1,12 @@
<script>
import marked from 'marked';
import { marked } from 'marked';
let text = `Some words are *italic*, some are **bold**`;
</script>
<textarea bind:value={text}></textarea>
{@html marked(text)}
<style>
textarea { width: 100%; height: 200px; }
</style>
<textarea bind:value={text}></textarea>
{@html marked(text)}

@ -0,0 +1,37 @@
<script>
let files;
$: if (files) {
// Note that `files` is of type `FileList`, not an Array:
// https://developer.mozilla.org/en-US/docs/Web/API/FileList
console.log(files);
for (const file of files) {
console.log(`${file.name}: ${file.size} bytes`);
}
}
</script>
<label for="avatar">Upload a picture:</label>
<input
accept="image/png, image/jpeg"
bind:files
id="avatar"
name="avatar"
type="file"
/>
<label for="many">Upload multiple files of any type:</label>
<input
bind:files
id="many"
multiple
type="file"
/>
{#if files}
<h2>Selected files:</h2>
{#each Array.from(files) as file}
<p>{file.name} ({file.size} bytes) </p>
{/each}
{/if}

@ -14,10 +14,6 @@
}
</script>
<style>
input { display: block; width: 500px; max-width: 100%; }
</style>
<h2>Insecurity questions</h2>
<form on:submit|preventDefault={handleSubmit}>
@ -36,4 +32,8 @@
</button>
</form>
<p>selected question {selected ? selected.id : '[waiting...]'}</p>
<p>selected question {selected ? selected.id : '[waiting...]'}</p>
<style>
input { display: block; width: 500px; max-width: 100%; }
</style>

@ -16,16 +16,10 @@
$: remaining = todos.filter(t => !t.done).length;
</script>
<style>
.done {
opacity: 0.4;
}
</style>
<h1>Todos</h1>
{#each todos as todo}
<div class:done={todo.done}>
<div>
<input
type=checkbox
bind:checked={todo.done}
@ -34,6 +28,7 @@
<input
placeholder="What needs to be done?"
bind:value={todo.text}
disabled={todo.done}
>
</div>
{/each}

@ -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);
}
// 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) {
// we can't rely on the built-in click event, because it fires
// after a drag — we have to listen for clicks ourselves
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) {
@ -51,6 +49,34 @@
}
</script>
<h1>Caminandes: Llamigos</h1>
<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={handleMove}
on:touchmove|preventDefault={handleMove}
on:mousedown={handleMousedown}
on:mouseup={handleMouseup}
bind:currentTime={time}
bind:duration
bind:paused>
<track kind="captions"/>
</video>
<div class="controls" style="opacity: {duration && showControls ? 1 : 0}">
<progress value="{(time / duration) || 0}"/>
<div class="info">
<span class="time">{format(time)}</span>
<span>click anywhere to {paused ? 'play' : 'pause'} / drag to seek</span>
<span class="time">{format(duration)}</span>
</div>
</div>
</div>
<style>
div {
position: relative;
@ -103,28 +129,3 @@
width: 100%;
}
</style>
<h1>Caminandes: Llamigos</h1>
<p>From <a href="https://cloud.blender.org/open-projects">Blender Open Projects</a>. CC-BY</p>
<div>
<video
poster="http://sveltejs.github.io/assets/caminandes-llamigos.jpg"
src="http://sveltejs.github.io/assets/caminandes-llamigos.mp4"
on:mousemove={handleMousemove}
on:mousedown={handleMousedown}
bind:currentTime={time}
bind:duration
bind:paused
></video>
<div class="controls" style="opacity: {duration && showControls ? 1 : 0}">
<progress value="{(time / duration) || 0}"/>
<div class="info">
<span class="time">{format(time)}</span>
<span>click anywhere to {paused ? 'play' : 'pause'} / drag to seek</span>
<span class="time">{format(duration)}</span>
</div>
</div>
</div>

@ -5,11 +5,6 @@
let text = 'edit me';
</script>
<style>
input { display: block; }
div { display: inline-block; }
</style>
<input type=range bind:value={size}>
<input bind:value={text}>
@ -17,4 +12,9 @@
<div bind:clientWidth={w} bind:clientHeight={h}>
<span style="font-size: {size}px">{text}</span>
</div>
</div>
<style>
input { display: block; }
div { display: inline-block; }
</style>

@ -20,7 +20,7 @@
const t = window.performance.now();
const r = 64 + (128 * x / canvas.width) + (64 * Math.sin(t / 1000));
const g = 64 + (128 * y / canvas.height) + (64 * Math.cos(t / 1000));
const g = 64 + (128 * y / canvas.height) + (64 * Math.cos(t / 1400));
const b = 128;
imageData.data[p + 0] = r;
@ -38,18 +38,18 @@
});
</script>
<canvas
bind:this={canvas}
width={32}
height={32}
></canvas>
<style>
canvas {
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>
<canvas
bind:this={canvas}
width={32}
height={32}
></canvas>

@ -10,19 +10,6 @@
const submit = () => dispatch('submit');
</script>
<style>
.keypad {
display: grid;
grid-template-columns: repeat(3, 5em);
grid-template-rows: repeat(4, 3em);
grid-gap: 0.5em
}
button {
margin: 0
}
</style>
<div class="keypad">
<button on:click={select(1)}>1</button>
<button on:click={select(2)}>2</button>
@ -37,4 +24,17 @@
<button disabled={!value} on:click={clear}>clear</button>
<button on:click={select(0)}>0</button>
<button disabled={!value} on:click={submit}>submit</button>
</div>
</div>
<style>
.keypad {
display: grid;
grid-template-columns: repeat(3, 5em);
grid-template-rows: repeat(4, 3em);
grid-gap: 0.5em
}
button {
margin: 0
}
</style>

@ -4,11 +4,25 @@
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>
<h1>Photo album</h1>
<div class="photos">
{#each photos as photo}
<figure>
<img src={photo.thumbnailUrl} alt={photo.title}>
<figcaption>{photo.title}</figcaption>
</figure>
{:else}
<!-- this block renders when photos.length === 0 -->
<p>loading...</p>
{/each}
</div>
<style>
.photos {
width: 100%;
@ -22,17 +36,3 @@
margin: 0;
}
</style>
<h1>Photo album</h1>
<div class="photos">
{#each photos as photo}
<figure>
<img src={photo.thumbnailUrl} alt={photo.title}>
<figcaption>{photo.title}</figcaption>
</figure>
{:else}
<!-- this block renders when photos.length === 0 -->
<p>loading...</p>
{/each}
</div>

@ -20,7 +20,7 @@
];
function handleKeydown(event) {
if (event.which === 13) {
if (event.key === 'Enter') {
const text = event.target.value;
if (!text) return;
@ -51,6 +51,20 @@
}
</script>
<div class="chat">
<h1>Eliza</h1>
<div class="scrollable" bind:this={div}>
{#each comments as comment}
<article class={comment.author}>
<span>{comment.text}</span>
</article>
{/each}
</div>
<input on:keydown={handleKeydown}>
</div>
<style>
.chat {
display: flex;
@ -90,17 +104,3 @@
border-radius: 1em 1em 0 1em;
}
</style>
<div class="chat">
<h1>Eliza</h1>
<div class="scrollable" bind:this={div}>
{#each comments as comment}
<article class={comment.author}>
<span>{comment.text}</span>
</article>
{/each}
</div>
<input on:keydown={handleKeydown}>
</div>

@ -4,7 +4,7 @@
let text = `Select some text and hit the tab key to toggle uppercase`;
async function handleKeydown(event) {
if (event.which !== 9) return;
if (event.key !== 'Tab') return;
event.preventDefault();
@ -27,11 +27,11 @@
}
</script>
<textarea value={text} on:keydown={handleKeydown}></textarea>
<style>
textarea {
width: 100%;
height: 200px;
}
</style>
<textarea value={text} on:keydown={handleKeydown}></textarea>
</style>

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

Loading…
Cancel
Save