diff --git a/site/content/blog/2021-06-01-whats-new-in-svelte-june-2021.md b/site/content/blog/2021-06-01-whats-new-in-svelte-june-2021.md new file mode 100644 index 0000000000..ab55f497f7 --- /dev/null +++ b/site/content/blog/2021-06-01-whats-new-in-svelte-june-2021.md @@ -0,0 +1,65 @@ +--- +title: What's new in Svelte: June 2021 +description: Progress towards SvelteKit 1.0 and tighter TypeScript/Svelte integrations in language tools +author: Daniel Sandoval +authorURL: https://desandoval.net +--- + +This month, we saw lots of contributions to SvelteKit and its docs. The language tools also got some new features, most notably deeper integration with Svelte files within JavaScript or TypeScript files. Let's jump into the updates... + +## New in SvelteKit +- `svelte.config.js` config files are now loaded in ESM format (`.js` instead of `.cjs`). +- AMP pages will now use the rendered CSS, rather than emitted CSS +- `svelte-check` has been added to the TypeScript template ([sveltejs/kit#1556](https://github.com/sveltejs/kit/pull/1556)) +- Support for https keypair [sveltejs/kit#1456](https://github.com/sveltejs/kit/pull/1456) +- Now bundling Vite with SvelteKit and using an upgraded version. Remove Vite from your `package.json` if it's there +- Etags for binary responses [sveltejs/kit#1382](https://github.com/sveltejs/kit/pull/1382) +- Renamed `$layout` to `__layout` and `$error` to `__error` +- Removed `getContext` in favor of `request.locals` +- Renamed `.svelte` output directory to `.svelte-kit`. Update your `.gitignore` accordingly +- `trailingSlash: 'never' | 'always' | 'ignore'` is now available in the config. This should make it easier to build sites that work with static hosting providers that expect a trailing slash for `index.html` pages, and provides an escape hatch for anyone that needs more complex behaviour. + +## Notable bug fixes in SvelteKit +- `adapter-netlify` got a fix [sveltejs/kit#1467](https://github.com/sveltejs/kit/pull/1467) and new documentation in the readme https://github.com/sveltejs/kit/tree/master/packages/adapter-netlify +- The router will no longer intercept navigation for URLs that the app does not own. This fixes a crash for apps that have `` elements on the page with the same origin but don't share a base path with the app. +- Hash only changes are now handled by the router fixing the browser's "back" navigation between hash changes in some circumstances. + + + +## New in Svelte & Language Tools +- Svelte 3.38.1 and 3.38.2 fixed an issue with hydration that was causing duplicate elements. If you're seeing this in your project, be sure to update the latest version! +- A new TypeScript plugin provides deeper integration with Svelte files within JavaScript or TypeScript files. This includes diagnostics, references and renaming of variables. It comes packaged with the VS Code extension but is turned off by default for now. You can enable it through [this setting](https://github.com/sveltejs/language-tools/tree/master/packages/svelte-vscode#svelteenable-ts-plugin). We encourage you to test it out and [provide feedback](https://github.com/sveltejs/language-tools/issues/580) +- In the latest version of `svelte-check` you can now provide the path to your `tsconfig.json` or `jsconfig.json`. Example: `svelte-check --tsconfig "./tsconfig.json"`. This ensures the diagnostics are only run on files that are referenced in that config. It also runs diagnostics on JavaScript and/or TypeScript files which removes the need to run another check (like `tsc --noEmit`) for non-Svelte files (`svelte-check` version [**1.6.0**](https://github.com/sveltejs/language-tools/releases/tag/svelte-check-1.6.0)) +- The VS Code extension and `svelte-check` got a new major release. Previously, properties that had no initializer (`export let foo;`) were only required if the user was using both TypeScript and activated `strict` mode. This is changed now: People using TypeScript, and those using `checkJs` also in JavaScript files, will now always have these properties marked as required (`svelte-check` version [**2.0.0**](https://github.com/sveltejs/language-tools/releases/tag/svelte-check-2.0.0), extension version [**105.0.0**](https://github.com/sveltejs/language-tools/releases/tag/extensions-105.0.0)) + +--- + +## Community Showcase + +**Apps & Sites** + +- [vidu](https://github.com/pa-nic/vidu) is a minimal web analytics collector and dashboard +- [River Runner](https://river-runner.samlearner.com/) is a virtual way to follow rivers downstream - built with Mapbox and Svelte. +- [JSDoc Type Generator](https://rafistrauss.github.io/jsdoc-generator/) generates JSDoc types for valid JSON. +- [pagereview.io](https://pagereview.io/) is a website feedback tool that lets you leave comments directly on the site being reviewed. +- [gamesroom.io](https://gamesroom.io/) is an online board game platform with video chat built-in. +- [Greedy Goblin](https://greedygoblin-fe11c.web.app/) is a recipe app for old-school Runescape players. +- [hashbrown.geopjr.dev](https://hashbrown.geopjr.dev/) is a GNOME-shell inspired webpage to learn about, explore the source code and download the Hashbrown GTK app ([link to source](https://github.com/GeopJr/Hashbrown/tree/website)). + + +**Libraries, Tools & Components** + +- [svelte-image-crop](https://novacbn.github.io/svelte-image-crop/) is a simple click'n'drag image cropping library using Web APIs. +- [svelte-datepicker](https://github.com/andrew-secret/svelte-datepicker) is a lightweight and inclusive date picker build with Svelte. +- [svelte-regex-router](https://www.npmjs.com/package/svelte-regex-router) is a simple, lightweight library for you to easily handle routes in your Svelte application. +- [Svelte Micro](https://www.npmjs.com/package/svelte-micro) is a light & reactive one-component router for Svelte. +- [svelte-entity-store](https://www.npmjs.com/package/svelte-entity-store) is to provide a simple, generic solution for storing collections of entity objects. +- [svelte-animation-store](https://github.com/joshnuss/svelte-animation-store) is a store that is based on Svelte's tweened store, that lets you pause, continue, reset, replay, reverse or adjust speed of a tween. + + +**Want to contribute a component?** Submit a [Component](https://sveltesociety.dev/components) to the Svelte Society site by making [a PR to this file](https://github.com/svelte-society/sveltesociety.dev/blob/master/src/pages/components/components.json). + + +## See you next month! + +Did we miss something? Join us on [Svelte Society](https://sveltesociety.dev/), [Reddit](https://www.reddit.com/r/sveltejs/) and [Discord](https://discord.com/invite/yy75DKs)! diff --git a/site/content/docs/02-template-syntax.md b/site/content/docs/02-template-syntax.md index 85b6ef553e..29d28bfb3d 100644 --- a/site/content/docs/02-template-syntax.md +++ b/site/content/docs/02-template-syntax.md @@ -393,7 +393,7 @@ When used around components, this will cause them to be reinstantiated and reini In a text expression, characters like `<` and `>` are escaped; however, with HTML expressions, they're not. -The expression should be valid standalone HTML — `{@html "
"}content{@html "
"}` will *not* work, because `` is not valid HTML. +The expression should be valid standalone HTML — `{@html "
"}content{@html "
"}` will *not* work, because `` is not valid HTML. It also will *not* compile Svelte code. > Svelte does not sanitize expressions before injecting HTML. If the data comes from an untrusted source, you must sanitize it, or you are exposing your users to an XSS vulnerability. @@ -585,7 +585,7 @@ Numeric input values are coerced; even though `input.value` is a string as far a --- -On `` elements with `type="file"`, you can use `bind:files` to get the [`FileList` of selected files](https://developer.mozilla.org/en-US/docs/Web/API/FileList). +On `` elements with `type="file"`, you can use `bind:files` to get the [`FileList` of selected files](https://developer.mozilla.org/en-US/docs/Web/API/FileList). It is readonly. ```sv @@ -1376,7 +1376,7 @@ Note that explicitly passing in an empty named slot will add that slot's name to ``` -#### [``](slot_let) +#### [``](slot_let) --- @@ -1475,6 +1475,8 @@ If `this` is falsy, no component is rendered. The `` element allows you to add event listeners to the `window` object without worrying about removing them when the component is destroyed, or checking for the existence of `window` when server-side rendering. +Contrary to `` this element can only be at the top level of your component and must never be inside a block or element. + ```sv

- initial - current + The emoji for { name } is { emoji }

\ No newline at end of file + diff --git a/site/content/tutorial/04-logic/05-keyed-each-blocks/app-b/App.svelte b/site/content/tutorial/04-logic/05-keyed-each-blocks/app-b/App.svelte index 37a19a67a8..0939d58b8a 100644 --- a/site/content/tutorial/04-logic/05-keyed-each-blocks/app-b/App.svelte +++ b/site/content/tutorial/04-logic/05-keyed-each-blocks/app-b/App.svelte @@ -2,11 +2,11 @@ import Thing from './Thing.svelte'; let things = [ - { id: 1, color: 'darkblue' }, - { id: 2, color: 'indigo' }, - { id: 3, color: 'deeppink' }, - { id: 4, color: 'salmon' }, - { id: 5, color: 'gold' } + { id: 1, name: 'apple' }, + { id: 2, name: 'banana' }, + { id: 3, name: 'carrot' }, + { id: 4, name: 'doughnut' }, + { id: 5, name: 'egg' }, ]; function handleClick() { @@ -18,6 +18,6 @@ Remove first thing -{#each things as thing (thing.id)} - +{#each things as thing (thing.id) } + {/each} diff --git a/site/content/tutorial/04-logic/05-keyed-each-blocks/app-b/Thing.svelte b/site/content/tutorial/04-logic/05-keyed-each-blocks/app-b/Thing.svelte index 28c3c65d05..02e6fa7640 100644 --- a/site/content/tutorial/04-logic/05-keyed-each-blocks/app-b/Thing.svelte +++ b/site/content/tutorial/04-logic/05-keyed-each-blocks/app-b/Thing.svelte @@ -1,24 +1,32 @@

- initial - current + The emoji for { name } is { emoji }

\ No newline at end of file + diff --git a/site/content/tutorial/04-logic/05-keyed-each-blocks/text.md b/site/content/tutorial/04-logic/05-keyed-each-blocks/text.md index 4affb89cd6..b990dead95 100644 --- a/site/content/tutorial/04-logic/05-keyed-each-blocks/text.md +++ b/site/content/tutorial/04-logic/05-keyed-each-blocks/text.md @@ -4,16 +4,18 @@ title: Keyed each blocks By default, when you modify the value of an `each` block, it will add and remove items at the *end* of the block, and update any values that have changed. That might not be what you want. -It's easier to show why than to explain. Click the 'Remove first thing' button a few times, and notice that it's removing `` components from the end and updating the `color` for those that remain. Instead, we'd like to remove the first `` component and leave the rest unaffected. +It's easier to show why than to explain. Click the 'Remove first thing' button a few times, and notice what happens: It removes the first `` component, but the *last* DOM node. Then it updates the `name` value in the remaining DOM nodes, but not the emoji. -To do that, we specify a unique identifier for the `each` block: +Instead, we'd like to remove only the first `` component and its DOM node, and leave the others unaffected. + +To do that, we specify a unique identifier (or "key") for the `each` block: ```html {#each things as thing (thing.id)} - + {/each} ``` -The `(thing.id)` tells Svelte how to figure out what changed. +Here, `(thing.id)` is the *key*, which tells Svelte how to figure out which DOM node to change when the component updates. > You can use any object as the key, as Svelte uses a `Map` internally — in other words you could do `(thing)` instead of `(thing.id)`. Using a string or number is generally safer, however, since it means identity persists without referential equality, for example when updating with fresh data from an API server. diff --git a/site/content/tutorial/06-bindings/09-each-block-bindings/text.md b/site/content/tutorial/06-bindings/09-each-block-bindings/text.md index 7e50966c32..9c352703f1 100644 --- a/site/content/tutorial/06-bindings/09-each-block-bindings/text.md +++ b/site/content/tutorial/06-bindings/09-each-block-bindings/text.md @@ -5,15 +5,17 @@ title: Each block bindings You can even bind to properties inside an `each` block. ```html - +{#each todos as todo} + - + +{/each} ``` -> Note that interacting with these `` elements will mutate the array. If you prefer to work with immutable data, you should avoid these bindings and use event handlers instead. \ No newline at end of file +> Note that interacting with these `` elements will mutate the array. If you prefer to work with immutable data, you should avoid these bindings and use event handlers instead. diff --git a/site/content/tutorial/08-stores/01-writable-stores/app-a/App.svelte b/site/content/tutorial/08-stores/01-writable-stores/app-a/App.svelte index ee542f789d..f2a4023f25 100644 --- a/site/content/tutorial/08-stores/01-writable-stores/app-a/App.svelte +++ b/site/content/tutorial/08-stores/01-writable-stores/app-a/App.svelte @@ -6,7 +6,7 @@ let count_value; - const unsubscribe = count.subscribe(value => { + count.subscribe(value => { count_value = value; }); @@ -15,4 +15,4 @@ - \ No newline at end of file + diff --git a/site/content/tutorial/08-stores/01-writable-stores/text.md b/site/content/tutorial/08-stores/01-writable-stores/text.md index 57c27411ea..247ef86e8d 100644 --- a/site/content/tutorial/08-stores/01-writable-stores/text.md +++ b/site/content/tutorial/08-stores/01-writable-stores/text.md @@ -24,4 +24,4 @@ Finally, in `Resetter.svelte`, implement `reset`: function reset() { count.set(0); } -``` \ No newline at end of file +``` diff --git a/site/content/tutorial/08-stores/02-auto-subscriptions/app-a/App.svelte b/site/content/tutorial/08-stores/02-auto-subscriptions/app-a/App.svelte index ee542f789d..f2a4023f25 100644 --- a/site/content/tutorial/08-stores/02-auto-subscriptions/app-a/App.svelte +++ b/site/content/tutorial/08-stores/02-auto-subscriptions/app-a/App.svelte @@ -6,7 +6,7 @@ let count_value; - const unsubscribe = count.subscribe(value => { + count.subscribe(value => { count_value = value; }); @@ -15,4 +15,4 @@ - \ No newline at end of file + diff --git a/site/content/tutorial/08-stores/02-auto-subscriptions/text.md b/site/content/tutorial/08-stores/02-auto-subscriptions/text.md index af584261f4..f80c4b2f72 100644 --- a/site/content/tutorial/08-stores/02-auto-subscriptions/text.md +++ b/site/content/tutorial/08-stores/02-auto-subscriptions/text.md @@ -2,9 +2,17 @@ title: Auto-subscriptions --- -The app in the previous example works, but there's a subtle bug — the `unsubscribe` function never gets called. If the component was instantiated and destroyed many times, this would result in a *memory leak*. +The app in the previous example works, but there's a subtle bug — the store is subscribed to, but never unsubscribed. If the component was instantiated and destroyed many times, this would result in a *memory leak*. -One way to fix it would be to use the `onDestroy` [lifecycle hook](tutorial/ondestroy): +Start by declaring `unsubscribe` in `App.svelte`: + +```js +const unsubscribe = count.subscribe(value => { + count_value = value; +}); +``` + +You now declared `unsubscribe`, but it still needs be to called, for example through the `onDestroy` [lifecycle hook](tutorial/ondestroy): ```html