Skip to content

Commit 1abac9d

Browse files
chore: ensure full page reloads between SvelteKit tutorial and other pages (and vice versa) (#301)
* ensure full page reloads between SvelteKit tutorial and other pages (and vice versa) * update docs * fix * use beforeNavigate (#308) * use beforeNavigate * Update apps/svelte.dev/src/routes/+layout.svelte --------- Co-authored-by: Simon H <[email protected]> --------- Co-authored-by: Rich Harris <[email protected]>
1 parent 04916af commit 1abac9d

File tree

5 files changed

+35
-14
lines changed

5 files changed

+35
-14
lines changed

apps/svelte.dev/README.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@ Cross-Origin-Embedder-Policy: require-corp
1515
Cross-Origin-Opener-Policy: same-origin
1616
```
1717

18-
Because we're doing soft navigation between pages, these headers need to be set for all responses, not just the ones from `/tutorial`.
19-
20-
The result of setting these headers is that the site can no longer embed URLs from other sites (like images from another domain) without those domains either having a `cross-origin-resource-policy: cross-origin` header (which most don't) or us adding the `crossorigin="anonymous"` attribute (or the experimental-only-working-in-chrome `credentialless` for iframes) to the elements that load those URLs.
18+
The result of setting these headers is that the site can no longer embed URLs from other sites (like images from another domain) without those domains either having a `cross-origin-resource-policy: cross-origin` header (which most don't) or us adding the `crossorigin="anonymous"` attribute (or the experimental-only-working-in-chrome `credentialless` for iframes) to the elements that load those URLs. For this reason, navigations between the SvelteKit tutorial and other pages (and vice versa) are full page navigations so the headers don't interfere with the rest of the page.
2119

2220
When writing content for the tutorial, you need to be aware of the differences of loading content:
2321

apps/svelte.dev/src/routes/+layout.svelte

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,30 @@
1-
<script>
1+
<script lang="ts">
22
import '@sveltejs/site-kit/styles/index.css';
3-
43
import { browser } from '$app/environment';
54
import { page } from '$app/stores';
6-
import { Icon, Shell, Banners } from '@sveltejs/site-kit/components';
7-
import { Nav, Separator } from '@sveltejs/site-kit/nav';
5+
import { Shell, Banners } from '@sveltejs/site-kit/components';
6+
import { Nav } from '@sveltejs/site-kit/nav';
87
import { Search, SearchBox } from '@sveltejs/site-kit/search';
98
import { injectSpeedInsights } from '@vercel/speed-insights/sveltekit';
9+
import { beforeNavigate } from '$app/navigation';
1010
1111
injectSpeedInsights();
1212
13+
// Make all navigations between SvelteKit-tutorial and non-SvelteKit-tutorial pages (and vice versa)
14+
// a full page navigation to ensure webcontainers get the correct origin restriction headers while
15+
// ensuring those headers don't interfere with the rest of the page. These headers would have bad
16+
// consequences on how we have to handle integration of images etc from other domains for example.
17+
beforeNavigate(({ from, to, cancel }) => {
18+
if (!from || !to) return;
19+
20+
if (
21+
from.url.pathname.startsWith('/tutorial/kit/') !== to.url.pathname.startsWith('/tutorial/kit')
22+
) {
23+
cancel();
24+
location.href = to.url.href;
25+
}
26+
});
27+
1328
let { data, children: layout_children } = $props();
1429
</script>
1530

apps/svelte.dev/src/routes/tutorial/[...slug]/+page.svelte

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
selected_name,
2020
solution
2121
} from './state.js';
22-
import { text_files } from './shared';
22+
import { needs_webcontainers, text_files } from './shared';
2323
import OutputRollup from './OutputRollup.svelte';
2424
import { page } from '$app/stores';
2525
@@ -317,10 +317,10 @@
317317
</section>
318318
319319
<section slot="b" class="preview">
320-
{#if /svelte$/.test($page.data.exercise.part.slug)}
321-
<OutputRollup />
322-
{:else}
320+
{#if needs_webcontainers($page.data.exercise)}
323321
<Output exercise={data.exercise} {paused} />
322+
{:else}
323+
<OutputRollup />
324324
{/if}
325325
</section>
326326
</SplitPane>

apps/svelte.dev/src/routes/tutorial/[...slug]/adapter.svelte.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { page } from '$app/stores';
33
import type { state as WCState } from '$lib/tutorial/adapters/webcontainer/index.svelte';
44
import type { state as RollupState } from '$lib/tutorial/adapters/rollup/index.svelte';
55
import type { Adapter, FileStub, Stub } from '$lib/tutorial';
6+
import { needs_webcontainers } from './shared';
67

78
let initial_load = true;
89
let use_rollup = $state(true);
@@ -35,9 +36,9 @@ export const adapter_state = new (class {
3536

3637
if (browser) {
3738
page.subscribe(($page) => {
38-
const slug = $page.data?.exercise?.part?.slug;
39-
if (slug) {
40-
use_rollup = /svelte$/.test(slug);
39+
const exercise = $page.data?.exercise;
40+
if (exercise) {
41+
use_rollup = !needs_webcontainers(exercise);
4142

4243
if (use_rollup) {
4344
load_rollup();

apps/svelte.dev/src/routes/tutorial/[...slug]/shared.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import type { Exercise } from '$lib/tutorial';
2+
13
export const text_files = new Set([
24
'.svelte',
35
'.txt',
@@ -10,3 +12,8 @@ export const text_files = new Set([
1012
'.md',
1113
'.env'
1214
]);
15+
16+
/** The SvelteKit tutorial needs web container technology */
17+
export function needs_webcontainers(exercise: Exercise | undefined) {
18+
return !!exercise && /sveltekit$/.test(exercise.part?.slug);
19+
}

0 commit comments

Comments
 (0)