Files
supabase/apps/ui-library/context/framework-context.tsx
Ali Waseem 1c2d28d5b3 chore: wrap local storage into helper methods that are safer (#46628)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

- Noticing our code we have many patterns of calling localstorage and
handling those errors
- We should add those in a single well tested file
- Handle those errors in the singleton which makes it easier for us to
debug customer issues. Logger is outputing local storage warnings for
feature we expose
- Side effect of this is random crashes on studio when local storage
isn't available or handled correctly

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Refactor**
* Improved browser storage handling across the app for more reliable
persistence and graceful behavior in restricted or non-browser
environments (settings, previews, charts, tabs, sign-in/session flows,
integrations, and UI state).

* **New Features**
* Introduced a safe storage layer to standardize and harden
local/session persistence.

* **Tests**
  * Added comprehensive tests covering the new safe storage behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-04 07:41:28 -06:00

48 lines
1.4 KiB
TypeScript

'use client'
import { safeLocalStorage } from 'common'
import { createContext, useContext, useEffect, useState } from 'react'
import { frameworkTitles } from '@/config/docs'
type Framework = keyof typeof frameworkTitles
type FrameworkContextType = {
framework: Framework
setFramework: (framework: Framework) => void
}
const FrameworkContext = createContext<FrameworkContextType | undefined>(undefined)
export function FrameworkProvider({ children }: { children: React.ReactNode }) {
const [framework, setFrameworkState] = useState<Framework>('nextjs')
// Initialize from localStorage on mount (client-side only)
useEffect(() => {
const storedFramework = safeLocalStorage.getItem('preferredFramework')
if (storedFramework && Object.keys(frameworkTitles).includes(storedFramework)) {
setFrameworkState(storedFramework as Framework)
}
}, [])
// Update localStorage when framework changes
const setFramework = (newFramework: Framework) => {
setFrameworkState(newFramework)
safeLocalStorage.setItem('preferredFramework', newFramework)
}
return (
<FrameworkContext.Provider value={{ framework, setFramework }}>
{children}
</FrameworkContext.Provider>
)
}
// Custom hook to use the framework context
export function useFramework() {
const context = useContext(FrameworkContext)
if (context === undefined) {
throw new Error('useFramework must be used within a FrameworkProvider')
}
return context
}