* Handle `width`/`height` attributes when spreading ([#6752](https://github.com/sveltejs/svelte/issues/6752))
* Add support for resize observer bindings (`<divbind:contentRect|contentBoxSize|borderBoxSize|devicePixelContentBoxSize>`) ([#8022](https://github.com/sveltejs/svelte/pull/8022))
## 3.58.0
- Add `bind:innerText` for `contenteditable` elements ([#3311](https://github.com/sveltejs/svelte/issues/3311))
readonly'bind:contentBoxSize'?:Array<{blockSize: number;inlineSize: number}>|undefined|null;// TODO make this ResizeObserverSize once we require TS>=4.4
readonly'bind:borderBoxSize'?:Array<{blockSize: number;inlineSize: number}>|undefined|null;// TODO make this ResizeObserverSize once we require TS>=4.4
readonly'bind:devicePixelContentBoxSize'?:Array<{blockSize: number;inlineSize: number}>|undefined|null;// TODO make this ResizeObserverSize once we require TS>=4.4
Components are the building blocks of Svelte applications. They are written into `.svelte` files, using a superset of HTML.
@ -24,7 +24,7 @@ A `<script>` block contains JavaScript that runs when a component instance is cr
### 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](#attributes-and-props) for more information).
Svelte uses the `export` keyword to mark a variable declaration as a _property_ or _prop_, which means it becomes accessible to consumers of the component (see the section on [attributes and props](/docs/basic-markup#attributes-and-props) for more information).
```svelte
<script>
@ -256,7 +256,7 @@ You cannot `export default`, since the default export is the component itself.
<scriptcontext="module">
let totalComponents = 0;
// this allows an importer to do e.g.
// the export keyword allows this function to imported with e.g.
// `import Example, { alertTotal } from './Example.svelte'`
export function alertTotal() {
alert(totalComponents);
@ -340,134 +340,3 @@ In that case, the `<style>` tag will be inserted as-is into the DOM, no scoping
</style>
</div>
```
## Tags
A lowercase tag, like `<div>`, denotes a regular HTML element. A capitalised tag, such as `<Widget>` or `<Namespace.Widget>`, indicates a _component_.
```svelte
<script>
import Widget from './Widget.svelte';
</script>
<div>
<Widget/>
</div>
```
## Attributes and props
By default, attributes work exactly like their HTML counterparts.
```svelte
<divclass="foo">
<buttondisabled>can't touch this</button>
</div>
```
As in HTML, values may be unquoted.
```svelte
<inputtype="checkbox"/>
```
Attribute values can contain JavaScript expressions.
```svelte
<ahref="page/{p}">page {p}</a>
```
Or they can _be_ JavaScript expressions.
```svelte
<buttondisabled={!clickable}>...</button>
```
Boolean attributes are included on the element if their value is [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy) and excluded if it's [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy).
All other attributes are included unless their value is [nullish](https://developer.mozilla.org/en-US/docs/Glossary/Nullish) (`null` or `undefined`).
```svelte
<inputrequired={false}placeholder="This input field is not required"/>
<divtitle={null}>This div has no title attribute</div>
```
An expression might include characters that would cause syntax highlighting to fail in regular HTML, so quoting the value is permitted. The quotes do not affect how the value is parsed:
```svelte
<buttondisabled={number!==42}>...</button>
```
When the attribute name and value match (`name={name}`), they can be replaced with `{name}`.
```svelte
<!-- These are equivalent -->
<button{disabled}>...</button>
<button{disabled}>...</button>
```
By convention, values passed to components are referred to as _properties_ or _props_ rather than _attributes_, which are a feature of the DOM.
As with elements, `name={name}` can be replaced with the `{name}` shorthand.
```svelte
<Widgetfoo={bar}answer={42}text="hello"/>
```
_Spread attributes_ allow many attributes or properties to be passed to an element or component at once.
An element or component can have multiple spread attributes, interspersed with regular ones.
```svelte
<Widget{...things}/>
```
_`$$props`_ references all props that are passed to a component, including ones that are not declared with `export`. It is not generally recommended, as it is difficult for Svelte to optimise. But it can be useful in rare cases – for example, when you don't know at compile time what props might be passed to a component.
```svelte
<Widget{...$$props}/>
```
_`$$restProps`_ contains only the props which are _not_ declared with `export`. It can be used to pass down other unknown attributes to an element in a component. It shares the same optimisation problems as _`$$props`_, and is likewise not recommended.
```svelte
<input{...$$restProps}/>
```
> The `value` attribute of an `input` element or its children `option` elements must not be set with spread attributes when using `bind:group` or `bind:checked`. Svelte needs to be able to see the element's `value` directly in the markup in these cases so that it can link it to the bound variable.
> Sometimes, the attribute order matters as Svelte sets attributes sequentially in JavaScript. For example, `<input type="range" min="0" max="1" value={0.5} step="0.1"/>`, Svelte will attempt to set the value to `1` (rounding up from 0.5 as the step by default is 1), and then set the step to `0.1`. To fix this, change it to `<input type="range" min="0" max="1" step="0.1" value={0.5}/>`.
> Another example is `<img src="..." loading="lazy" />`. Svelte will set the img `src` before making the img element `loading="lazy"`, which is probably too late. Change this to `<img loading="lazy" src="...">` to make the image lazily loaded.
## Text expressions
```svelte
{expression}
```
Text can also contain JavaScript expressions:
> If you're using a regular expression (`RegExp`) [literal notation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#literal_notation_and_constructor), you'll need to wrap it in parentheses.
```svelte
<h1>Hello {name}!</h1>
<p>{a} + {b} = {a + b}.</p>
<div>{/^[A-Za-z ]+$/.test(value) ? x : y}</div>
```
## Comments
You can use HTML comments inside components.
```svelte
<!-- this is a comment! --><h1>Hello world</h1>
```
Comments beginning with `svelte-ignore` disable warnings for the next block of markup. Usually, these are accessibility warnings; make sure that you're disabling them for a good reason.
A lowercase tag, like `<div>`, denotes a regular HTML element. A capitalised tag, such as `<Widget>` or `<Namespace.Widget>`, indicates a _component_.
```svelte
<script>
import Widget from './Widget.svelte';
</script>
<div>
<Widget/>
</div>
```
## Attributes and props
By default, attributes work exactly like their HTML counterparts.
```svelte
<divclass="foo">
<buttondisabled>can't touch this</button>
</div>
```
As in HTML, values may be unquoted.
```svelte
<inputtype="checkbox"/>
```
Attribute values can contain JavaScript expressions.
```svelte
<ahref="page/{p}">page {p}</a>
```
Or they can _be_ JavaScript expressions.
```svelte
<buttondisabled={!clickable}>...</button>
```
Boolean attributes are included on the element if their value is [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy) and excluded if it's [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy).
All other attributes are included unless their value is [nullish](https://developer.mozilla.org/en-US/docs/Glossary/Nullish) (`null` or `undefined`).
```svelte
<inputrequired={false}placeholder="This input field is not required"/>
<divtitle={null}>This div has no title attribute</div>
```
An expression might include characters that would cause syntax highlighting to fail in regular HTML, so quoting the value is permitted. The quotes do not affect how the value is parsed:
```svelte
<buttondisabled={number!==42}>...</button>
```
When the attribute name and value match (`name={name}`), they can be replaced with `{name}`.
```svelte
<!-- These are equivalent -->
<button{disabled}>...</button>
<button{disabled}>...</button>
```
By convention, values passed to components are referred to as _properties_ or _props_ rather than _attributes_, which are a feature of the DOM.
As with elements, `name={name}` can be replaced with the `{name}` shorthand.
```svelte
<Widgetfoo={bar}answer={42}text="hello"/>
```
_Spread attributes_ allow many attributes or properties to be passed to an element or component at once.
An element or component can have multiple spread attributes, interspersed with regular ones.
```svelte
<Widget{...things}/>
```
_`$$props`_ references all props that are passed to a component, including ones that are not declared with `export`. It is not generally recommended, as it is difficult for Svelte to optimise. But it can be useful in rare cases – for example, when you don't know at compile time what props might be passed to a component.
```svelte
<Widget{...$$props}/>
```
_`$$restProps`_ contains only the props which are _not_ declared with `export`. It can be used to pass down other unknown attributes to an element in a component. It shares the same optimisation problems as _`$$props`_, and is likewise not recommended.
```svelte
<input{...$$restProps}/>
```
> The `value` attribute of an `input` element or its children `option` elements must not be set with spread attributes when using `bind:group` or `bind:checked`. Svelte needs to be able to see the element's `value` directly in the markup in these cases so that it can link it to the bound variable.
> Sometimes, the attribute order matters as Svelte sets attributes sequentially in JavaScript. For example, `<input type="range" min="0" max="1" value={0.5} step="0.1"/>`, Svelte will attempt to set the value to `1` (rounding up from 0.5 as the step by default is 1), and then set the step to `0.1`. To fix this, change it to `<input type="range" min="0" max="1" step="0.1" value={0.5}/>`.
> Another example is `<img src="..." loading="lazy" />`. Svelte will set the img `src` before making the img element `loading="lazy"`, which is probably too late. Change this to `<img loading="lazy" src="...">` to make the image lazily loaded.
## Text expressions
```svelte
{expression}
```
Text can also contain JavaScript expressions:
> If you're using a regular expression (`RegExp`) [literal notation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#literal_notation_and_constructor), you'll need to wrap it in parentheses.
```svelte
<h1>Hello {name}!</h1>
<p>{a} + {b} = {a + b}.</p>
<div>{/^[A-Za-z ]+$/.test(value) ? x : y}</div>
```
## Comments
You can use HTML comments inside components.
```svelte
<!-- this is a comment! --><h1>Hello world</h1>
```
Comments beginning with `svelte-ignore` disable warnings for the next block of markup. Usually, these are accessibility warnings; make sure that you're disabling them for a good reason.
The `svelte/store` module exports functions for creating [readable](/docs/svelte-store#readable), [writable](/docs/svelte-store#writable) and [derived](/docs/svelte-store#derived) stores.
Keep in mind that you don't _have_ to use these functions to enjoy the [reactive `$store` syntax](/docs/dot-svelte-files#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/svelte-store#derived).
Keep in mind that you don't _have_ to use these functions to enjoy the [reactive `$store` syntax](/docs/svelte-components#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/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/dot-svelte-files#4-prefix-stores-with-$-to-access-their-values) to see what a correct implementation looks like.
This makes it possible to wrap almost any other reactive state handling library for use in Svelte. Read more about the [store contract](/docs/svelte-components#4-prefix-stores-with-$-to-access-their-values) to see what a correct implementation looks like.
By default, custom elements are compiled with `accessors: true`, which means that any [props](/docs/dot-svelte-files#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/basic-markup#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>`.
@ -9,16 +9,16 @@ If you do want to use a database, set it up on [Supabase](https://supabase.com)
Run the site sub-project:
```bash
pnpm install
pnpm dev
npm install
npm run dev
```
and navigate to [localhost:5173](http://localhost:5173).
The first time you run the site locally, it will update the list of Contributors and REPL dependencies. After this it won't run again unless you force it by running:
The first time you run the site locally, it will update the list of Contributors, REPL dependencies and examples data that is used on the [examples page](https://svelte-dev-2.vercel.app/examples). After this it won't run again unless you force it by running:
```bash
pnpm update
npm run update
```
## Running using the local copy of Svelte
@ -56,11 +56,153 @@ The GitHub app requires a specific callback URL, and so cannot be used with the
## Building the site
To build the website, run `pnpm build`. The output can be found in `build`.
To build the website, run `npm run build`. The output can be found in `.vercel`.
## Testing
Tests can be run using `pnpm test`.
Tests can be run using `npm run test`.
## Docs & other content
All the docs, examples, tutorials, FAQ live in the [site/content](../../site/content) directory, outside the site sub-project. If you modify these, and your app server is running, you will need to reload the page to see the changes.
Following are the file structures of the different kind of documentations
### Docs structure
```txt
- site/content/docs
- 01-getting-started <-Category
- meta.json <-Metadata
- 01-introduction.md <-Page
- 02-template-syntax <-Category
- meta.json <-Metadata
- 01-logic-blocks.md <-Page
- 02-special-tags.md <-Page
- 03-element-directives.md <-Page
```
If you are creating a new page, it must be within a category. That is, you can't have a .md file in the `docs` directory's root level. You may have a category without any pages in it, but you can't have a page without a category. You can add the new page in an existing category, or create your own, for example:
```txt
- site/content/docs
<!-- Rest of the docs -->
+ - 07-my-new-category <-Category
+ - 01-my-new-page.md <-Page
```
The numbers in front of category folders and page files are just for ordering the content. They may not be consecutive. Their only purpose exists for the docs author to decide how the content is arranged.
> Because of hardcoded regex in docs processing code, the numbers prefixed to pages are REQUIRED and _must be two digits_.
The name of the file is what determines the URL of the page. For example, the URL of `01-introduction.md` is `https://svelte.dev/docs/introduction`. The URL of `02-special-tags.md` is `https://svelte.dev/docs/special-tags`. Even though these are in categories, the URL does not contain the category name. Keep this in mind when creating new pages, as two pages with same slug in different categories will clash.
**meta.json** files contain data about the current category. At the time of writing it only has one field: `title`
```json
{
"title": "Getting Started"
}
```
This `title` field is used as category text in the sidebar on docs page.
Every single .md file in the docs must have frontmatter with `title` in it. For example, this is how the frontmatter of `02-logic-blocks.md` looks like:
```md
---
title: .svelte files
---
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.
<!-- REST OF THE CONTENT -->
```
You need not specify a h1 tag(or in markdown, a `#`). The `title` field in the frontmatter will be used as the h1 tag.
The headings in the document must start from h2(`##`). That is, you can't have an h1 tag in the document. h2(`##`), h3(`###`), h4(`####`) and h5(`#####`) are all valid.
#### Processing
Docs are processed in the [`src/lib/server/docs`](./src/lib/server/docs) folder. `get-docs-data.js` is responsible for reading the docs from filesystem and accumulating the metadata in forms of arrays and objects. `docs/index.js` has the code responsible for _rendering_ the markdown files into HTML. These functions are then imported into [src/routes/docs/+layout.server.js](./src/routes/docs/+layout.server.js) and used to generate docs list, and similarly in [src/routes/docs/%5Bslug%5D/+page.server.js](./src/routes/docs/%5Bslug%5D/%2Bpage.server.js) and are rendered there.
### Tutorial structure
```txt
- site/content/tutorial
- 01-introduction <-Category
- meta.json <-Metadata
- 01-basics <-Page'scontentfolder
- text.md <-Textcontentoftutorial
- app-a <-Theinitialappfolder
- App.svelte
- store.js
- app-b <-Thefinalappfolder.Notalwayspresent
- App.svelte
- store.js
```
Similar to how docs are structured, only difference is that the pages are in a folders, and their content is in a `text.md` file. Alongside, are two folders, _app-a_ and _app-b_. These are the initial and final apps respectively. The initial app is the one that the tutorial shows, and the final app is the one that the tutorial switches to after user clicks on the **Show me** button.
> app-b is not always there. This means that the _Show me_ button is not present for that page.
The naming scheme of docs is followed here as well. The numbers in front of the folders are just for ordering the content. They may not be consecutive. Their only purpose exists for the tutorial author to decide how the content is arranged. _And they are compulsary_.
#### Processing
Tutorials are processed in the [`src/lib/server/tutorial`](./src/lib/server/tutorial) folder. `get-tutorial-data.js` is responsible for reading the tutorials from filesystem and accumulating the metadata in forms of arrays and objects. `tutorial/index.js` has the code responsible for _rendering_ the markdown files into HTML. These functions are then imported into [src/routes/tutorial/+layout.server.js](./src/routes/tutorial/%2Blayout.server.js) and used to generate tutorial list, and similarly in [src/routes/tutorial/%5Bslug%5D/+page.server.js](./src/routes/tutorial/%5Bslug%5D/%2Bpage.server.js) and are rendered there.
### Examples structure
```txt
- site/content/examples
- 00-introduction <-Category
- meta.json <-Metadata
- 00-hello-world <-Page'scontentfolder
- meta.json <-Metadata
- App.svelte <-codefiles
- 01-reactivity <-Category
- meta.json <-Metadata
- 00-reactive-assignments <-Page'scontentfolder
- meta.json <-Metadata
- App.svelte <-codefiles
```
Similar to the tutorial, only difference: There is no `text.md`, and the code files are kept right in the folder, not in `app-` folder.
Same naming scheme as docs and tutorial is followed.
#### Processing
Examples are processed in the [`src/lib/server/examples`](./src/lib/server/examples) folder. `get-examples-data.js` is responsible for reading the examples from filesystem and accumulating the metadata in forms of arrays and objects. `examples/index.js` has the code responsible for _rendering_ the markdown files into HTML. These functions are then imported into [src/routes/examples/%5Bslug%5D/+page.server.js](./src/routes/examples/%5Bslug%5D/%2Bpage.server.js) and are rendered there.
### Blog structure
```txt
- site/content/blog
- 2019-01-01-my-first-post.md
- 2019-01-02-my-second-post.md
```
Compared to the rest of the content, blog posts are not in a folder. They are placed at the root of `site/content/blog` folder. The name of the file is the date of the post, followed by the slug of the post. The slug is the URL where the blog post is available. For example, the slug of `2019-01-01-my-first-post.md` is `my-first-post`.
All the metadata about the blog post is mentioned in the frontematter of a post. For example, this is how the frontmatter of [2023-03-09-zero-config-type-safety.md](../../site/content/blog/2023-03-09-zero-config-type-safety.md) looks like:
```md
---
title: Zero-effort type safety
description: More convenience and correctness, less boilerplate
author: Simon Holthausen
authorURL: https://twitter.com/dummdidumm_
---
```
#### Processing
Blog posts are processed in the [`src/lib/server/blog`](./src/lib/server/blog) folder. `get-blog-data.js` is responsible for reading the blog posts from filesystem and accumulating the metadata in forms of arrays and objects. `blog/index.js` has the code responsible for _rendering_ the markdown files into HTML. These functions are then imported into [src/routes/blog/+page.svelte](./src/routes/blog/%2Bpage.server.js), where they show the list of blogs. The rendering function is imported in [src/routes/blog/%5Bslug%5D/+page.server.js](./src/routes/blog/%5Bslug%5D/%2Bpage.server.js) and renders the individual blog post there.