Dynamic theme using Remote (async) styles in MUI React?

Viewed 11

I'm working on a SaaS in which a particular entity (my customer) and customize their styles like primary color, secondary color, font-family etc.

How can I load remote data inside the theme?

I've tried several conditional theming so far, I think theme is not accepting async data

My data should come like this from the API response.

{ "styles": { "primary": "#087f5b", "bodyBackground": "#f8f9fa", "bodyText": "#343a40" } }

I need to fetch it on the fly as soon as user is loading the page, I'm ready to show a loading screen as well while the theme data comes from the server.

Here's what I've tried so far. It works when I'm trying || operator to add conditional primary color, but is there any better way of doing it ?

import { Box, Button, CircularProgress } from "@mui/material";
import { createTheme, ThemeProvider } from "@mui/material/styles";
import { useQuery } from "@tanstack/react-query";
import { useState } from "react";
import { api } from "./axios.instance";

function App() {
  const [siteData, setSiteData] = useState([]);
  const { loading } = useQuery(
    ["orgData"],
    async () => await api.get("/styles"),
    {
      onSuccess: (res) => setSiteData(res.data),
    }
  );

  const theme = createTheme({
    palette: {
      primary: {
        main: siteData.primary || "#000",
      },
    },
  });

  return (
    <>
      {loading ? (
        <CircularProgress />
      ) : (
        <ThemeProvider theme={theme}>
          <Box>
            <Button variant="contained">Button</Button>
          </Box>
        </ThemeProvider>
      )}
    </>
  );
}

export default App;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

0 Answers
Related