Direct Answers
- Plain context values cannot be updated reactively.
setContext captures the value at render time; mutating the source variable does not propagate to children that called getContext. A new context would be required, but the idiomatic fix is to place a Svelte store in context instead.
- Use a writable store as the context value. Initialize it on mount with
Intl.DateTimeFormat().resolvedOptions().timeZone. Subscribe in children or use $store in Svelte 4 / $derived in Svelte 5. No built-in browser event exists for time-zone changes; poll or listen to Intl.DateTimeFormat recreation if runtime detection is required.
- No public roadmap entry for a built-in reactive locale or time-zone store. Neither Svelte 4 nor the upcoming Svelte 5 runes API has announced such a feature. The ecosystem relies on user-land stores.
Why Plain Context Fails
setContext(key, value) runs once per component instance during initialization. The value is stored internally and returned by getContext(key) without any subscription mechanism. Changing the variable passed to setContext later does not trigger re-evaluation in descendants.
Recommended Pattern: Store in Context
<script>
import { writable, get } from 'svelte/store';
import { setContext, getContext } from 'svelte';
const LOCALE_CTX = 'app:locale';
export function provideLocale(initial = 'en-US') {
const store = writable(initial);
setContext(LOCALE_CTX, store);
return store;
}
export function useLocale() {
return getContext(LOCALE_CTX);
}
</script>
Children call const locale = useLocale() and read $locale (Svelte 4) or $derived(locale) (Svelte 5 runes). Updating locale.set('de-DE') anywhere propagates reactively.
Time-Zone Synchronization
function createTimeZoneStore() {
const initial = Intl.DateTimeFormat().resolvedOptions().timeZone;
const store = writable(initial);
// Optional: detect changes via polling (no native event)
let last = initial;
const interval = setInterval(() => {
const current = Intl.DateTimeFormat().resolvedOptions().timeZone;
if (current !== last) {
last = current;
store.set(current);
}
}, 60_000);
return {
subscribe: store.subscribe,
destroy: () => clearInterval(interval)
};
}
Call createTimeZoneStore() at the root, place the returned store in context, and clean up destroy() on unmount.
Verification Steps
- In a child component, log
getContext('app:locale') before and after a parent calls store.set('new-value'). The store reference stays identical; the subscribed value updates.
- Open the browser devtools console, change the system time zone, and confirm the polling interval picks up the new
Intl.DateTimeFormat().resolvedOptions().timeZone within the interval window.
Diagnostic Detail Needed
Which Svelte version are you targeting (4.x or 5.x with runes)? The reactivity syntax ($store vs $derived) and context behavior differ slightly, and Svelte 5 may introduce new patterns.