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>