SCOTT SPENCE
Developer Relations Engineer
Scott Spence
CMS
Serverless functions enable front-end developers to add powerful "back-end" logic to our apps just by writing JavaScript — no devops, no servers, just results.
The thing to focus on with headless is that it abstracts away the view, leaving development teams to focus on using their preferred tech stack
Modern Frontends Live
Visually create, edit and publish content in real-time with Storyblok’s Visual Editor.
Let content creators, marketers and editor, see their changes in real time
Experience your content in different viewports without leaving the app
Publicly available preview link available for external stakeholders
Collaboration made simple: leave comments, discuss and share feedback.
query {
products {
# from Storyblok
name
description {
richtext
}
# from 3rd party API
inventory {
inStock
}
# rest of query
}
}
function component() {
let count = 0;
const button = document.createElement('button');
button.textContent = `Clicks: ${count}`;
button.addEventListener('click', () => {
count += 1;
button.textContent = `Clicks: ${count}`;
});
return button;
}
<script>
let count = 0;
</script>
<button on:click={() => count += 1}>
Clicks: {count}
</button>
(Developer Experience)
Client side
(the browser)
<script>
import { createClient, setContextClient } from '@urql/svelte'
import '../global.css'
const client = createClient({
url: `https://rickandmortyapi.com/graphql`,
})
setContextClient(client)
</script>
<main class="container">
<slot />
</main>
<style>
/* layout styles go here */
</style>
src/routes/
+layout.svelte
<script>
import { getContextClient, gql, queryStore } from '@urql/svelte'
const charactersQueryStore = queryStore({
client: getContextClient(),
query: gql`
query AllCharacters {
characters {
results {
name
id
image
}
}
}
`,
})
</script>
<div class="wrapper">
{#if $charactersQueryStore.fetching}
<p>Loading...</p>
{:else if $charactersQueryStore.error}
<p>Oopsie! {$charactersQueryStore.error.message}</p>
{:else}
{#each $charactersQueryStore.data.characters.results as character}
<section>
<a data-sveltekit-prefetch href={`/character/${character?.id}`}>
<img src={character?.image} alt={character?.name} />
<h2>{character?.name}</h2>
</a>
</section>
{/each}
{/if}
</div>
<style>
/* page styles go here */
</style>
src/routes/
+page.svelte
src/routes/
+page.svelte
<script>
import { getContextClient, gql, queryStore } from '@urql/svelte'
const charactersQueryStore = queryStore({
client: getContextClient(),
query: gql`
query AllCharacters {
characters {
results {
name
id
image
}
}
}
`,
})
</script>
<pre>{JSON.stringify($charactersQueryStore, null, 2)}</pre>
SvelteKit debug 👀
{
"characters": {
"results": [
{
"name": "Rick Sanchez",
"id": "1",
"image": "https://rickandmortyapi.com/api/character/avatar/1.jpeg",
"__typename": "Character"
},
{
"name": "Morty Smith",
"id": "2",
"image": "https://rickandmortyapi.com/api/character/avatar/2.jpeg",
"__typename": "Character"
},
{
"name": "Summer Smith",
"id": "3",
"image": "https://rickandmortyapi.com/api/character/avatar/3.jpeg",
"__typename": "Character"
},
],
"__typename": "Characters"
}
}
src/routes/
+page.svelte
<script>
import { getContextClient, gql, queryStore } from '@urql/svelte'
const charactersQueryStore = queryStore({
client: getContextClient(),
query: gql`
query AllCharacters {
characters {
results {
name
id
image
}
}
}
`,
})
</script>
<div class="wrapper">
{#if $charactersQueryStore.fetching}
<p>Loading...</p>
{:else if $charactersQueryStore.error}
<p>Oopsie! {$charactersQueryStore.error.message}</p>
{:else}
{#each $charactersQueryStore.data.characters.results as character}
<section>
<a data-sveltekit-prefetch href={`/character/${character?.id}`}>
<img src={character?.image} alt={character?.name} />
<h2>{character?.name}</h2>
</a>
</section>
{/each}
{/if}
</div>
<style>
/* page styles go here */
</style>
src/routes/
+page.svelte
src/routes/
+page.svelte
<div class="wrapper">
{#if $charactersQueryStore.fetching}
<p>Loading...</p>
{:else if $charactersQueryStore.error}
<p>Oopsie! {$charactersQueryStore.error.message}</p>
{:else}
{#each $charactersQueryStore.data.characters.results as character}
<section>
<a data-sveltekit-prefetch href={`/character/${character?.id}`}>
<img src={character?.image} alt={character?.name} />
<h2>{character?.name}</h2>
</a>
</section>
{/each}
{/if}
</div>