Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions apps/svelte.dev/content/blog/2020-07-17-svelte-and-typescript.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,18 +66,18 @@ You first need to set up [`svelte-preprocess`](https://github.com/sveltejs/svelt

In a Rollup project, that would look like this — note that we also need to install `@rollup/plugin-typescript` so that Rollup can handle `.ts` files:

```diff
+ import autoPreprocess from 'svelte-preprocess';
+ import typescript from '@rollup/plugin-typescript';
```js
+++import autoPreprocess from 'svelte-preprocess';
import typescript from '@rollup/plugin-typescript';+++

export default {
...,
plugins: [
svelte({
+ preprocess: autoPreprocess()
}),
+ typescript({ sourceMap: !production })
]
// ...,
plugins: [
svelte({
+++preprocess: autoPreprocess()+++
}),
+++typescript({ sourceMap: !production })+++
]
}
```

Expand Down
52 changes: 26 additions & 26 deletions apps/svelte.dev/content/blog/2023-03-09-zero-config-type-safety.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const database = {
}
};
// ---cut---
// src/routes/blog/[slug]/+page.server.ts
/// file: src/routes/blog/[slug]/+page.server.ts
import type { ServerLoadEvent } from '@sveltejs/kit';

export async function load(event: ServerLoadEvent) {
Expand All @@ -42,16 +42,16 @@ This works, but we can do better. Notice that we accidentally wrote `event.param

This is where our automatic type generation comes in. Every route directory has a hidden `$types.d.ts` file with route-specific types:

```diff
// src/routes/blog/[slug]/+page.server.ts
-import type { ServerLoadEvent } from '@sveltejs/kit';
+import type { PageServerLoadEvent } from './$types';
```js
/// file: src/routes/blog/[slug]/+page.server.ts
---import type { ServerLoadEvent } from '@sveltejs/kit';---
+++import type { PageServerLoadEvent } from './$types';+++

export async function load(event: PageServerLoadEvent) {
return {
- post: await database.getPost(event.params.post)
+ post: await database.getPost(event.params.slug)
};
return {
---post: await database.getPost(event.params.post)---
+++post: await database.getPost(event.params.slug)+++
};
}
```

Expand All @@ -60,7 +60,7 @@ This reveals our typo, as it now errors on the `params.post` property access. Be
After we have loaded our data, we want to display it in our `+page.svelte`. The same type generation mechanism ensures that the type of `data` is correct:

```svelte
<!-- src/routes/blog/[slug]/+page.svelte -->
/// file: src/routes/blog/[slug]/+page.svelte
<script lang="ts">
import type { PageData } from './$types';

Expand All @@ -78,7 +78,7 @@ When running the dev server or the build, types are auto-generated. Thanks to th

```ts
// @errors: 2344 2694 2307
// $types.d.ts
/// file: $types.d.ts
import type * as Kit from '@sveltejs/kit';

// types inferred from the routing tree
Expand All @@ -100,7 +100,7 @@ export type PageData = Kit.ReturnType<

We don't actually write `$types.d.ts` into your `src` directory — that would be messy, and no-one likes messy code. Instead, we use a TypeScript feature called [`rootDirs`](https://www.typescriptlang.org/tsconfig#rootDirs), which lets us map ‘virtual’ directories to real ones. By setting `rootDirs` to the project root (the default) and additionally to `.svelte-kit/types` (the output folder of all the generated types) and then mirroring the route structure inside it we get the desired behavior:

```
```tree
// on disk:
.svelte-kit/
├ types/
Expand All @@ -115,8 +115,9 @@ src/
│ │ ├ [slug]/
│ │ │ ├ +page.server.ts
│ │ │ └ +page.svelte
```


```tree
// what TypeScript sees:
src/
├ routes/
Expand All @@ -131,24 +132,23 @@ src/

Thanks to the automatic type generation we get advanced type safety. Wouldn't it be great though if we could just omit writing the types at all? As of today you can do exactly that:

```diff
// src/routes/blog/[slug]/+page.server.ts
-import type { PageServerLoadEvent } from './$types';
```js
/// file: src/routes/blog/[slug]/+page.server.ts
---import type { PageServerLoadEvent } from './$types';---

-export async function load(event: PageServerLoadEvent) {
+export async function load(event) {
return {
post: await database.getPost(event.params.post)
};
export async function load(event---: PageServerLoadEvent---) {
return {
post: await database.getPost(event.params.post)
};
}
```

```diff
<!-- src/routes/blog/[slug]/+page.svelte -->
```svelte
/// file: src/routes/blog/[slug]/+page.svelte
<script lang="ts">
- import type { PageData } from './$types';
- export let data: PageData;
+ export let data;
---import type { PageData } from './$types';---
---export let data: PageData;---
+++export let data;+++
</script>
```

Expand Down
4 changes: 2 additions & 2 deletions apps/svelte.dev/content/blog/2023-08-31-view-transitions.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ However, until now, you couldn’t easily use this API in a SvelteKit app, since
You can trigger a view transition by calling `document.startViewTransition` and passing a callback that updates the DOM somehow. For our purposes today, SvelteKit will update the DOM as the user navigates. Once the callback finishes, the browser will transition to the new page state — by default, it does a crossfade between the old and the new states.

```js
// @errors: 2339
// @errors: 2339 2304
const domUpdate = async () => {};
// ---cut---
document.startViewTransition(async () => {
Expand Down Expand Up @@ -162,7 +162,7 @@ Now, the header will not transition in and out on navigation, but the rest of th
> [!DETAILS] Fixing the types
> Since `startViewTransition` is not supported by all browsers, your IDE may not know that it exists. To make the errors go away and get the correct typings, add the following to your `app.d.ts`:
>
> ```ts
> ```dts
> declare global {
> // preserve any customizations you have here
> namespace App {
Expand Down
59 changes: 29 additions & 30 deletions apps/svelte.dev/content/blog/2023-09-20-runes.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,11 @@ Runes are symbols that influence the Svelte compiler. Whereas Svelte today uses

For example, to declare a piece of reactive state, we can use the `$state` rune:

```diff
```svelte
<!--- file: App.svelte --->
<script>
- let count = 0;
+ let count = $state(0);
---let count = 0;---
+++let count = $state(0);+++

function increment() {
count += 1;
Expand Down Expand Up @@ -94,60 +94,59 @@ export function createCounter() {

Because this implements the _store contract_ — the returned value has a `subscribe` method — we can reference the store value by prefixing the store name with `$`:

```diff
```svelte
<!--- file: App.svelte --->
<script>
/// file: App.svelte
+ import { createCounter } from './counter.js';
+
+ const counter = createCounter();
- let count = 0;
-
- function increment() {
- count += 1;
- }
+++ import { createCounter } from './counter.js';

const counter = createCounter();+++
--- let count = 0;

function increment() {
count += 1;
}---
</script>

-<button on:click={increment}>
- clicks: {count}
+<button on:click={counter.increment}>
+ clicks: {$counter}
---<button on:click={increment}>
clicks: {count}---
+++<button on:click={counter.increment}>
clicks: {$counter}+++
</button>
```

This works, but it's pretty weird! We've found that the store API can get rather unwieldy when you start doing more complex things.

With runes, things get much simpler:

```diff
```js
/// file: counter.svelte.js
-import { writable } from 'svelte/store';
---import { writable } from 'svelte/store';---

export function createCounter() {
- const { subscribe, update } = writable(0);
+ let count = $state(0);
---const { subscribe, update } = writable(0);---
+++let count = $state(0);+++

return {
- subscribe,
- increment: () => update((n) => n + 1)
+ get count() { return count },
+ increment: () => count += 1
};
---subscribe,---
---increment: () => update((n) => n + 1)---
+++get count() { return count },+++
+++increment: () => count += 1+++
};
}
```

```diff
```svelte
<!--- file: App.svelte --->
<script>
- import { createCounter } from './counter.js';
+ import { createCounter } from './counter.svelte.js';
import { createCounter } from './counter+++.svelte+++.js';

const counter = createCounter();
</script>

<button on:click={counter.increment}>
- clicks: {$counter}
+ clicks: {counter.count}
---clicks: {$counter}---
+++clicks: {counter.count}+++
</button>
```

Expand Down
31 changes: 18 additions & 13 deletions apps/svelte.dev/content/docs/kit/20-core-concepts/20-load.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,26 +110,26 @@ export async function load() {

Data returned from layout `load` functions is available to child `+layout.svelte` components and the `+page.svelte` component as well as the layout that it 'belongs' to.

```diff
```svelte
/// file: src/routes/blog/[slug]/+page.svelte
<script>
+ import { page } from '$app/stores';
+++import { page } from '$app/stores';+++

/** @type {import('./$types').PageData} */
export let data;

+ // we can access `data.posts` because it's returned from
+ // the parent layout `load` function
+ $: index = data.posts.findIndex(post => post.slug === $page.params.slug);
+ $: next = data.posts[index - 1];
+++ // we can access `data.posts` because it's returned from
// the parent layout `load` function
$: index = data.posts.findIndex(post => post.slug === $page.params.slug);
$: next = data.posts[index - 1];+++
</script>

<h1>{data.post.title}</h1>
<div>{@html data.post.content}</div>

+{#if next}
+ <p>Next post: <a href="/blog/{next.slug}">{next.title}</a></p>
+{/if}
+++{#if next}
<p>Next post: <a href="/blog/{next.slug}">{next.title}</a></p>
{/if}+++
```

> [!NOTE] If multiple `load` functions return data with the same key, the last one 'wins' — the result of a layout `load` returning `{ a: 1, b: 2 }` and a page `load` returning `{ b: 3, c: 4 }` would be `{ a: 1, b: 3, c: 4 }`.
Expand Down Expand Up @@ -381,16 +381,21 @@ In `+page.js` or `+layout.js` it will return data from parent `+layout.js` files

Take care not to introduce waterfalls when using `await parent()`. Here, for example, `getData(params)` does not depend on the result of calling `parent()`, so we should call it first to avoid a delayed render.

```diff
```js
/// file: +page.js
// @filename: ambient.d.ts
declare function getData(params: Record<string, string>): Promise<{ meta: any }>

// @filename: index.js
// ---cut---
/** @type {import('./$types').PageLoad} */
export async function load({ params, parent }) {
- const parentData = await parent();
---const parentData = await parent();---
const data = await getData(params);
+ const parentData = await parent();
+++const parentData = await parent();+++

return {
...data
...data,
meta: { ...parentData.meta, ...data.meta }
};
}
Expand Down
Loading
Loading