Svelte Context API: The Secret Messenger System 🎒
The Story: A School With Secret Notes
Imagine a big school building. In this school, there’s a principal (the parent component) who wants to share important information with all the classrooms (child components) below them.
But here’s the problem: The principal can’t just shout! That would be chaos. And passing notes through every single teacher one by one? Too slow!
The Solution? A magic bulletin board system called the Context API.
The principal posts a note on the bulletin board, and ANY classroom in that building can read it instantly. No shouting. No passing notes through everyone. Just magic!
What is Context API?
Think of Context like a shared backpack that a parent gives to all its children. Any child component can reach into this backpack and grab what they need.
Without Context:
Parent → passes data → Child1 → Child2 → Child3
(So much work! Called "prop drilling")
With Context:
Parent (shares backpack)
↓
All children can grab from backpack directly!
1. setContext: Putting Stuff in the Backpack 🎒
setContext is how a parent component shares something with all its children.
Simple Example
Think of it like this:
- Mom puts a cookie jar in the family backpack
- Any family member can now grab cookies!
<!-- Parent.svelte -->
<script>
import { setContext } from 'svelte';
// Put "cookie jar" in the backpack
// Key = 'snacks' (the label)
// Value = 'chocolate cookies' (the actual thing)
setContext('snacks', 'chocolate cookies');
</script>
<Child />
Key Points:
- First argument: The “key” (a label to find it later)
- Second argument: The “value” (what you’re sharing)
- Must be called during component setup (not inside functions or events)
2. getContext: Grabbing from the Backpack 🍪
getContext is how a child component retrieves what the parent shared.
Simple Example
Think of it like this:
- Kid opens the family backpack
- Looks for the jar labeled “snacks”
- Grabs the cookies!
<!-- Child.svelte -->
<script>
import { getContext } from 'svelte';
// Open backpack, find 'snacks' label
const mySnack = getContext('snacks');
console.log(mySnack);
// Output: "chocolate cookies"
</script>
<p>I got: {mySnack}!</p>
Key Points:
- Use the same key that was used in
setContext - Returns the value that was stored
- Only works if an ancestor set that context
3. Context Scope: Who Can See the Backpack? 🏠
Here’s the magic rule: Only children inside the parent can access its context.
The Family Tree Rule
graph TD A["Grandparent sets context"] --> B["Parent"] B --> C["Child ✅ can access"] B --> D["Another Child ✅ can access"] A --> E["Uncle"] E --> F["Cousin ❌ different branch"]
Real Example
<!-- App.svelte -->
<script>
import { setContext } from 'svelte';
setContext('theme', 'dark');
</script>
<Header /> <!-- ✅ Can access 'theme' -->
<Main>
<Sidebar /> <!-- ✅ Can access 'theme' -->
<Content /> <!-- ✅ Can access 'theme' -->
</Main>
<Footer /> <!-- ✅ Can access 'theme' -->
Scope Rules:
| Component Location | Can Access? |
|---|---|
| Direct child | ✅ Yes |
| Grandchild | ✅ Yes |
| Great-grandchild | ✅ Yes |
| Sibling (same level) | ❌ No |
| Completely different tree | ❌ No |
Overriding Context
A nested component can create its own context with the same key:
<!-- Parent.svelte -->
<script>
import { setContext } from 'svelte';
setContext('color', 'blue');
</script>
<!-- Nested.svelte (inside Parent) -->
<script>
import { setContext } from 'svelte';
// Override for children below THIS component
setContext('color', 'red');
</script>
Children of Nested will get 'red', not 'blue'!
4. Context with Reactivity: The Magic Updating Backpack ✨
Plain context values don’t update automatically. If you change them, children won’t know!
The Problem:
<!-- This WON'T work for updates! -->
<script>
import { setContext } from 'svelte';
let count = 0;
setContext('counter', count);
// If count changes, children won't see it!
</script>
The Solution: Use a Store! 📻
Svelte stores are like radio stations. When the station plays new music, everyone tuned in hears it instantly!
<!-- Parent.svelte -->
<script>
import { setContext } from 'svelte';
import { writable } from 'svelte/store';
// Create a radio station (store)
const count = writable(0);
// Share the station, not just one song
setContext('counter', count);
function increment() {
count.update(n => n + 1);
}
</script>
<button on:click={increment}>
Add One
</button>
<Child />
<!-- Child.svelte -->
<script>
import { getContext } from 'svelte';
// Tune into the radio station
const count = getContext('counter');
</script>
<!-- $count auto-subscribes to updates! -->
<p>Count is: {$count}</p>
Why This Works:
graph TD A["Parent creates store"] --> B["Shares store via context"] B --> C["Child 1 subscribes"] B --> D["Child 2 subscribes"] B --> E["Child 3 subscribes"] A --> F["Parent updates store"] F --> G["ALL children see update!"]
Quick Pattern for Reactive Context
<!-- Store + Context Pattern -->
<script>
import { setContext } from 'svelte';
import { writable } from 'svelte/store';
// Step 1: Create store
const user = writable({ name: 'Guest' });
// Step 2: Share via context
setContext('user', {
// Share the store
user,
// Share update function too!
updateName: (newName) => {
user.update(u => ({...u, name: newName}));
}
});
</script>
<!-- Any Child Component -->
<script>
import { getContext } from 'svelte';
// Get both store and function
const { user, updateName } = getContext('user');
</script>
<p>Hello, {$user.name}!</p>
<button on:click={() => updateName('Alice')}>
Change Name
</button>
Complete Example: Theme Switcher 🌓
Let’s build something real! A theme system that any component can use.
The Provider (Parent)
<!-- ThemeProvider.svelte -->
<script>
import { setContext } from 'svelte';
import { writable } from 'svelte/store';
const theme = writable('light');
setContext('theme', {
theme,
toggle: () => {
theme.update(t =>
t === 'light' ? 'dark' : 'light'
);
}
});
</script>
<slot />
The Consumer (Any Child)
<!-- ThemeButton.svelte -->
<script>
import { getContext } from 'svelte';
const { theme, toggle } = getContext('theme');
</script>
<button
on:click={toggle}
class:dark={$theme === 'dark'}
>
Current: {$theme}
</button>
Quick Summary 📝
| Concept | What It Does | Think Of It As |
|---|---|---|
setContext |
Share data with children | Putting in backpack |
getContext |
Retrieve shared data | Taking from backpack |
| Context Scope | Only descendants can access | Family tree rule |
| Context + Store | Make context reactive | Radio station |
Golden Rules 🌟
- Call context functions during setup - not in event handlers or async code
- Use the same key for set and get
- Wrap in stores if you need reactivity
- Share objects with stores AND helper functions for best results
- Context flows down - children access parent’s context, never the reverse
You Did It! 🎉
You now understand Svelte’s Context API:
- setContext puts things in the shared backpack
- getContext takes things out
- Scope means only children in the tree can access
- Stores make context values update everywhere automatically
Go build something amazing! 🚀
