Skip to content

chore: ensure full page reloads between SvelteKit tutorial and other pages (and vice versa) #301

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Oct 9, 2024
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
4 changes: 1 addition & 3 deletions apps/svelte.dev/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
```

Because we're doing soft navigation between pages, these headers need to be set for all responses, not just the ones from `/tutorial`.

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

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

Expand Down
23 changes: 19 additions & 4 deletions apps/svelte.dev/src/routes/+layout.svelte
Original file line number Diff line number Diff line change
@@ -1,15 +1,30 @@
<script>
<script lang="ts">
import '@sveltejs/site-kit/styles/index.css';

import { browser } from '$app/environment';
import { page } from '$app/stores';
import { Icon, Shell, Banners } from '@sveltejs/site-kit/components';
import { Nav, Separator } from '@sveltejs/site-kit/nav';
import { Shell, Banners } from '@sveltejs/site-kit/components';
import { Nav } from '@sveltejs/site-kit/nav';
import { Search, SearchBox } from '@sveltejs/site-kit/search';
import { injectSpeedInsights } from '@vercel/speed-insights/sveltekit';
import { beforeNavigate } from '$app/navigation';

injectSpeedInsights();

// Make all navigations between SvelteKit-tutorial and non-SvelteKit-tutorial pages (and vice versa)
// a full page navigation to ensure webcontainers get the correct origin restriction headers while
// ensuring those headers don't interfere with the rest of the page. These headers would have bad
// consequences on how we have to handle integration of images etc from other domains for example.
beforeNavigate(({ from, to, cancel }) => {
if (!from || !to) return;

if (
from.url.pathname.startsWith('/tutorial/kit/') !== to.url.pathname.startsWith('/tutorial/kit')
) {
cancel();
location.href = to.url.href;
}
});

let { data, children: layout_children } = $props();
</script>

Expand Down
8 changes: 4 additions & 4 deletions apps/svelte.dev/src/routes/tutorial/[...slug]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
selected_name,
solution
} from './state.js';
import { text_files } from './shared';
import { needs_webcontainers, text_files } from './shared';
import OutputRollup from './OutputRollup.svelte';
import { page } from '$app/stores';

Expand Down Expand Up @@ -317,10 +317,10 @@
</section>

<section slot="b" class="preview">
{#if /svelte$/.test($page.data.exercise.part.slug)}
<OutputRollup />
{:else}
{#if needs_webcontainers($page.data.exercise)}
<Output exercise={data.exercise} {paused} />
{:else}
<OutputRollup />
{/if}
</section>
</SplitPane>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { page } from '$app/stores';
import type { state as WCState } from '$lib/tutorial/adapters/webcontainer/index.svelte';
import type { state as RollupState } from '$lib/tutorial/adapters/rollup/index.svelte';
import type { Adapter, FileStub, Stub } from '$lib/tutorial';
import { needs_webcontainers } from './shared';

let initial_load = true;
let use_rollup = $state(true);
Expand Down Expand Up @@ -35,9 +36,9 @@ export const adapter_state = new (class {

if (browser) {
page.subscribe(($page) => {
const slug = $page.data?.exercise?.part?.slug;
if (slug) {
use_rollup = /svelte$/.test(slug);
const exercise = $page.data?.exercise;
if (exercise) {
use_rollup = !needs_webcontainers(exercise);

if (use_rollup) {
load_rollup();
Expand Down
7 changes: 7 additions & 0 deletions apps/svelte.dev/src/routes/tutorial/[...slug]/shared.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { Exercise } from '$lib/tutorial';

export const text_files = new Set([
'.svelte',
'.txt',
Expand All @@ -10,3 +12,8 @@ export const text_files = new Set([
'.md',
'.env'
]);

/** The SvelteKit tutorial needs web container technology */
export function needs_webcontainers(exercise: Exercise | undefined) {
return !!exercise && /sveltekit$/.test(exercise.part?.slug);
}
Loading