Back to blogs
Blog
Writing in public
Longer posts — published here first, then cross-posted to Dev.to with a canonical URL back to this site.
Blog
Longer posts — published here first, then cross-posted to Dev.to with a canonical URL back to this site.
Back to blogs
Back to blogs
Postnextjs, typescript, localstorage, darkmode
useLocalStorage the custom hook strapped this together to help save and retrieve...
Date published

Modify your nextauth client and add a callbacks section that will get the access token from the...

You can select the scopes you want to request from GitHub/your oauthprovider in the login page, and...

Why You Might Still Pick Next.js Over TanStack Start From a TanStack Start...
user-theme and token from the localstoragewas working on a react vite app and had to port it over to Next Js the ported next js app and i very quickly discovered that localStorage worked a little differently n Nextjs and i need it because that's where i was saving my personal access token and theme preferences which lead me down a rabbit hole which resulted in the following custom hook for that
123import { useState,useEffect,useReducer } from 'react';4import { Viewer } from './../types/usertypes';56interface State{7token:string|null8theme:string|null9mainuser?:Viewer10error?:string11}121314export const useLocalStorge=()=>{1516const [loading, setLoading] = useState(true);17const [ state,dispatch] = useReducer(generalReducer,undefined);18useEffect(() => {19 const gen = window.localStorage.general;20 if(gen){21 dispatch({ type: "INIT", payload: JSON.parse(gen) });22 }23 setLoading(false)24}, [])252627useEffect(() => {28 const colorTheme = state?.theme === "dark" ? "light" : "dark";29 const root = window.document.documentElement;30 // console.log("colorTheme ==== ", colorTheme);31 root.classList.remove(colorTheme);32 // console.log("theme reset to ==== ",state?.theme)33 if(state?.theme){34 root.classList.add(state?.theme);35 }3637}, [state?.theme]);38394041useEffect(() => {42if(state)43window.localStorage.setItem("general",JSON.stringify(state))44}, [state])4546return {loading ,state ,dispatch}47}48495051525354function generalReducer(state:State, action:any) {55switch (action.type) {5657 case "INIT":58 return action.payload;59 case "THEME":60 return {...state,theme:action.payload}61 case "TOKEN":62 return {...state,token:action.payload}63 case "ERROR":64 return {...state,error:action.payload}6566 default:67 return state;68}69}7071
and you consume it like
1import "../styles/globals.css";2import type { AppProps } from "next/app";3import { ReactQueryDevtools } from "react-query/devtools";4import { QueryClient, QueryClientProvider } from "react-query";5import { Layout } from "../components/Layout";6import { useLocalStorge } from "./../utils/hooks/useLocalStorge";7import GlobalContext from "../utils/context/GlobalsContext";89const queryClient = new QueryClient({10 defaultOptions: {11 queries: {12 refetchOnWindowFocus: false,13 refetchOnMount: false,14 refetchOnReconnect: false,15 retry: false,16 staleTime: 5 * 60 * 1000,17 },18 },19});2021function MyApp({ Component, pageProps }: AppProps) {22 const local = useLocalStorge();23 // console.log("local state ==== ",local?.state)2425 // console.log("initial value in local storage ==== ", value);2627 return (28 <QueryClientProvider client={queryClient}>29 <GlobalContext.Provider30 value={{ value: local?.state, updateValue: local?.dispatch }}31 >32 <Layout local={local}>33 <Component {...pageProps} />34 <ReactQueryDevtools />35 </Layout>36 </GlobalContext.Provider>37 </QueryClientProvider>38 );39}4041export default MyApp;4243
the cotext is optonnal but it looks like this
1import React, { Dispatch } from "react";2import { Viewer } from './../types/usertypes';34export interface Value {5 token: string | null;6 theme:string7 error?: string;8 mainuser?:Viewer9}10interface Type {11 value: Value;12 updateValue:Dispatch<any>13}1415const init_data: Type = {16 value:{token:null,theme:"light"},17 updateValue: (any) => {},18};1920const GlobalContext = React.createContext(init_data);21export default GlobalContext;22