Next.js Discord

Discord Forum

Dynamic theming

Answered
Oriental Scops-Owl posted this in #help-forum
Open in Discord
Avatar
Oriental Scops-OwlOP
Hi, i have a SaaS application i want to allow the customer / app owner the ability to theme certain areas of the application.

what would be the best approach for something like this? i would be storing the theme values inside of my database and retrieving them via API call.

would it be best to fetch the theme palette from the API on the initial loading of the app, and store them in local storage or server-side cookie, then use a theme provider of some sort to load the values into CSS variables?

any link or guide to a tutorial how to do something similar would be appreciated. thanks
Answered by B33fb0n3
would it be best to fetch the theme palette from the API on the initial loading of the app
Yes

and store them in local storage or server-side cookie
No, why you want to, when they are saved in the cache or in css variables?

then use a theme provider of some sort to load the values into CSS variables?
Yes and of course use these css variables then
View full answer

15 Replies

Avatar
B33fb0n3
would it be best to fetch the theme palette from the API on the initial loading of the app
Yes

and store them in local storage or server-side cookie
No, why you want to, when they are saved in the cache or in css variables?

then use a theme provider of some sort to load the values into CSS variables?
Yes and of course use these css variables then
Answer
Avatar
Oriental Scops-OwlOP
thanks. i kind of figured out a solution without a theme provider. may still add one though.
Avatar
B33fb0n3
How does your „no theme provider“ solution look like?
Avatar
Oriental Scops-OwlOP
im using MUI theme provider in my main layout component:

    <AppRouterCacheProvider>
      <ThemeProvider theme={theme}>
        <GrubDialog
          open={locationDialogOpen}
          onClose={closeLocationDialog}
          title="Select a Location"
        >
          <LocationForm onSelect={handleUpdateLocation} location={currentLocation} />
        </GrubDialog>
        <>
          <Header onOpenLocations={toggleLocationDialog} properties={properties}/>
          <main className={styles.appContainer}>{children}</main>
          <Footer />
        </>
        <MobileNav onOpenLocations={toggleLocationDialog} />
      </ThemeProvider>
    </AppRouterCacheProvider>
i have this to fetch my tenant store properties and generate a theme object :

  const fetchProperties = async(): Promise<void> => {
    if (currentLocation) {
      setLoading(true)
      const resp = await fetch(`/api/locations/${currentLocation?.id!}/properties`)
      const json = await resp.json()
      setProperties(json.data)
      if (json.data.length > 0) {
        setTheme(generateTheme(json.data))
      }
      setLoading(false)
    }
  }
the fetchProperties is a useEffect on page load and whenever the store location changes
the only other thing i have left to make work is adjusting root CSS variables from within the container layout component
so when the app first loads in the browser, it fetches all of the properties for the selected store location and generates a theme object for MUI to use. it shows a loading text/headline until everything is loaded. seems to be working. its not the fastest solution, but i cant afford to build the customer app everytime he updates his settings. this is too costly with regards to resources and complicates everything
once the app loads, as you flip through router pages, everything is stored inside cache so its still pretty fast. its just the initial loading of the web app is a bit slow sometimes
Avatar
Oriental Scops-OwlOP
so technically, i am using a theme provider, but it was the MUI provider.
Avatar
B33fb0n3
You might want to take a look at this thread if you want to know how I solved the problem with the help of many other people: https://nextjs-forum.com/post/1246500950345252924#message-1246500950345252924
Avatar
Oriental Scops-OwlOP
thanks. im satisfied with the current solution but i will give it a look over
Avatar
B33fb0n3
Great to hear that. Does this message solves your issue: https://nextjs-forum.com/post/1260707521207996416#message-1260855115032690690

?
Avatar
Oriental Scops-OwlOP
yep thats basically what i did
Avatar
B33fb0n3
Happy to help 🙂