flat-fuchsia
flat-fuchsia16mo ago

Change Logo in default Sidebar

Hey where can I change the Sidebar Logo in refine? I cant find it ...
No description
31 Replies
kapa.ai
kapa.ai16mo ago
Hey @eliot0801! I'm the kapa.ai support bot. I've searched through the docs to try to answer your question. :wave: ---------------------- To change the logo in the default Sidebar in refine, you need to customize the default Sider. The <Title> component is responsible for rendering the logo inside the <Sider> component. First, check out the example on how to customize the Sider Menu here (https://refine.dev/docs/examples/customization/customSider/). Then, in your custom Sider component, replace the default refine logo with your own logo. Here's an example of how to do this:
import { Sider, Title } from "@pankod/refine";
import YourLogo from "path/to/your/logo";

const CustomSider: React.FC = () => {
return (
<Sider>
<Title>
<a href="/">
<img src={YourLogo} alt="Your Logo" />
</a>
</Title>
{/* ... other Sider components */}
</Sider>
);
};
import { Sider, Title } from "@pankod/refine";
import YourLogo from "path/to/your/logo";

const CustomSider: React.FC = () => {
return (
<Sider>
<Title>
<a href="/">
<img src={YourLogo} alt="Your Logo" />
</a>
</Title>
{/* ... other Sider components */}
</Sider>
);
};
Finally, use your custom Sider component in your refine configuration. ----------------------
kapa.ai
kapa.ai16mo ago
<@244579825140891648> kapa.ai is still learning and improving, please let us how it did by reacting below
criminal-purple
criminal-purple16mo ago
if you are using refine@3 you can change title like this: https://refine.dev/docs/3.xx.xx/api-reference/core/components/refine-config/#title if you are using refine@4 you use title prop of layout
<Layout> Title={() => <div>my logo</div>}
</Layout>
<Layout> Title={() => <div>my logo</div>}
</Layout>
flat-fuchsia
flat-fuchsia16mo ago
Yes i am using refine@4. Can you give me more specific code i dont understand how to do this
criminal-purple
criminal-purple16mo ago
when you use create refine-app we are adding default <Layout> according to your selected UI package. this is generated code from create refine-app when selected MUI. app.tsx
<BrowserRouter>
<GitHubBanner />
<ThemeProvider theme={LightTheme}>
<CssBaseline />
<GlobalStyles
styles={{ html: { WebkitFontSmoothing: "auto" } }}
/>
<RefineSnackbarProvider>
<Refine
routerProvider={routerProvider}
dataProvider={dataProvider(
"https://api.fake-rest.refine.dev",
)}
notificationProvider={notificationProvider}
resources={[
{
name: "posts",
list: "/posts",
create: "/posts/create",
edit: "/posts/edit/:id",
},
]}
options={{
syncWithLocation: true,
warnWhenUnsavedChanges: true,
}}
>
<Routes>
<Route
element={
<Layout>
<Outlet />
</Layout>
}
>
<Route
index
element={
<NavigateToResource resource="posts" />
}
/>

<Route path="/posts">
<Route index element={<PostList />} />
<Route
path="create"
element={<PostCreate />}
/>
<Route
path="edit/:id"
element={<PostEdit />}
/>
</Route>

<Route path="*" element={<ErrorComponent />} />
</Route>
</Routes>
<UnsavedChangesNotifier />
</Refine>
</RefineSnackbarProvider>
</ThemeProvider>
</BrowserRouter>
<BrowserRouter>
<GitHubBanner />
<ThemeProvider theme={LightTheme}>
<CssBaseline />
<GlobalStyles
styles={{ html: { WebkitFontSmoothing: "auto" } }}
/>
<RefineSnackbarProvider>
<Refine
routerProvider={routerProvider}
dataProvider={dataProvider(
"https://api.fake-rest.refine.dev",
)}
notificationProvider={notificationProvider}
resources={[
{
name: "posts",
list: "/posts",
create: "/posts/create",
edit: "/posts/edit/:id",
},
]}
options={{
syncWithLocation: true,
warnWhenUnsavedChanges: true,
}}
>
<Routes>
<Route
element={
<Layout>
<Outlet />
</Layout>
}
>
<Route
index
element={
<NavigateToResource resource="posts" />
}
/>

<Route path="/posts">
<Route index element={<PostList />} />
<Route
path="create"
element={<PostCreate />}
/>
<Route
path="edit/:id"
element={<PostEdit />}
/>
</Route>

<Route path="*" element={<ErrorComponent />} />
</Route>
</Routes>
<UnsavedChangesNotifier />
</Refine>
</RefineSnackbarProvider>
</ThemeProvider>
</BrowserRouter>
You can use Layout component's Title prop to change
flat-fuchsia
flat-fuchsia16mo ago
No description
flat-fuchsia
flat-fuchsia16mo ago
Do you mean this?
criminal-purple
criminal-purple16mo ago
oh sorry. are u using nextjs ?
flat-fuchsia
flat-fuchsia16mo ago
nooo typescript.tsx
criminal-purple
criminal-purple16mo ago
yes you can use this layout component
flat-fuchsia
flat-fuchsia16mo ago
Okey wish me good luck, thx you Alican It doesnt work, I dont unterstand
criminal-purple
criminal-purple16mo ago
i will debug and return you
flat-fuchsia
flat-fuchsia16mo ago
Ey Alican, we are using next.js Sorry
extended-salmon
extended-salmon16mo ago
we are using nextjs and mui. We copied the pages from inferencer and just want to change the Sidebar Icon (when collapsed and when opened). In V3 this was very easy, now I cant find it 😄
criminal-purple
criminal-purple16mo ago
Hi, i created nextjs project from scratch you can use this code snippet
const MyTitle = ({ collapsed }: { collapsed: boolean }) => {
if (collapsed) {
return <h2>MT</h2>
}

return <h2>My Title</h2>
}

function MyApp({ Component, pageProps }: AppPropsWithLayout): JSX.Element {
const renderComponent = () => {
if (Component.noLayout) {
return <Component {...pageProps} />
}

return (
<Layout Header={Header} Title={(props) => <MyTitle collapsed={props.collapsed} />}>
<Component {...pageProps} />
</Layout>
)
}
const MyTitle = ({ collapsed }: { collapsed: boolean }) => {
if (collapsed) {
return <h2>MT</h2>
}

return <h2>My Title</h2>
}

function MyApp({ Component, pageProps }: AppPropsWithLayout): JSX.Element {
const renderComponent = () => {
if (Component.noLayout) {
return <Component {...pageProps} />
}

return (
<Layout Header={Header} Title={(props) => <MyTitle collapsed={props.collapsed} />}>
<Component {...pageProps} />
</Layout>
)
}
flat-fuchsia
flat-fuchsia16mo ago
Thank you, it worked 🙂
criminal-purple
criminal-purple16mo ago
🙏🏻 🚀
extended-salmon
extended-salmon16mo ago
Thank you so much! 🙂
extended-salmon
extended-salmon16mo ago
Hm, we found a bug. We want to use a img as a header element, not a h2. Changing that works, but only on the list page, not on the edit page and so on...
No description
No description
extended-salmon
extended-salmon16mo ago
const MyTitle = ({ collapsed }: { collapsed: boolean }) => {
if (collapsed) {
return <a href="/"> <img src={'images/sider/logo.png'} width={45} /> </a>;
}

return <a href="/"> <img src={'images/sider/banner.png'} width={200} /> </a>;
};
const MyTitle = ({ collapsed }: { collapsed: boolean }) => {
if (collapsed) {
return <a href="/"> <img src={'images/sider/logo.png'} width={45} /> </a>;
}

return <a href="/"> <img src={'images/sider/banner.png'} width={200} /> </a>;
};
criminal-purple
criminal-purple16mo ago
probably your path is broken on src '/images/sider/banner.png'can you try this ? i added "/" to start
extended-salmon
extended-salmon16mo ago
I'll try it in a sec. somehow some pages do not work anymore, even on the last commit, on which everything was fine yesterday
criminal-purple
criminal-purple16mo ago
i don't think it's releated to title component
extended-salmon
extended-salmon16mo ago
no it isnt. I've found the issue: If you clear the cookies and start from the beginning and the first action you do is "show" on a item, it doesnt work. It only works, if u open the item on the edit page. After you've done that at least one time, the show page works
No description
criminal-purple
criminal-purple16mo ago
can you give me your show page code
extended-salmon
extended-salmon16mo ago
1/2
export default function CaseShow() {
const { queryResult } = useShow();
const { data, isLoading } = queryResult;

const record = data?.data;

const date = new Date(record?.createdAt);

const dateFormat = date.getDate() + "/" + ('0' + (date.getMonth() + 1)).slice(-2) + "/" + date.getFullYear() + ", " + ('0' + (date.getHours() - 1)).slice(-2) + ":" + ('0' + (date.getMinutes())).slice(-2) + ":" + ('0' + (date.getSeconds())).slice(-2);

return (
<Show isLoading={isLoading}>
<Stack gap={1}>
<Typography variant="body1" fontWeight="bold">
Id
</Typography>
<NumberField value={record?.id ?? ""} />
<Typography variant="body1" fontWeight="bold">
Created At
</Typography>
<TextField value={dateFormat} />
<Typography variant="body1" fontWeight="bold">
Title
</Typography>
<TextField value={record?.title} />
<Typography variant="body1" fontWeight="bold">
Short Description
</Typography>
<TextField value={record?.shortDescription} />
<Typography variant="body1" fontWeight="bold">
Status
</Typography>
<TextField value={record?.state} />
<Typography variant="body1" fontWeight="bold">
Ranked
</Typography>

export default function CaseShow() {
const { queryResult } = useShow();
const { data, isLoading } = queryResult;

const record = data?.data;

const date = new Date(record?.createdAt);

const dateFormat = date.getDate() + "/" + ('0' + (date.getMonth() + 1)).slice(-2) + "/" + date.getFullYear() + ", " + ('0' + (date.getHours() - 1)).slice(-2) + ":" + ('0' + (date.getMinutes())).slice(-2) + ":" + ('0' + (date.getSeconds())).slice(-2);

return (
<Show isLoading={isLoading}>
<Stack gap={1}>
<Typography variant="body1" fontWeight="bold">
Id
</Typography>
<NumberField value={record?.id ?? ""} />
<Typography variant="body1" fontWeight="bold">
Created At
</Typography>
<TextField value={dateFormat} />
<Typography variant="body1" fontWeight="bold">
Title
</Typography>
<TextField value={record?.title} />
<Typography variant="body1" fontWeight="bold">
Short Description
</Typography>
<TextField value={record?.shortDescription} />
<Typography variant="body1" fontWeight="bold">
Status
</Typography>
<TextField value={record?.state} />
<Typography variant="body1" fontWeight="bold">
Ranked
</Typography>

2/2
<Checkbox checked={record?.isRanked} disabled />
<Typography variant="body1" fontWeight="bold">
Timebased
</Typography>
<Checkbox checked={record?.timeBased} disabled />
<Typography variant="body1" fontWeight="bold">
Likes
</Typography>
<NumberField value={record?.likes} />
<Typography variant="body1" fontWeight="bold">
Favorites
</Typography>
<NumberField value={record?.numberOfFavorites} />
<Typography variant="body1" fontWeight="bold">
Difficulty
</Typography>
<TextField value={record?.difficulty} />
</Stack>
</Show>
);
}
<Checkbox checked={record?.isRanked} disabled />
<Typography variant="body1" fontWeight="bold">
Timebased
</Typography>
<Checkbox checked={record?.timeBased} disabled />
<Typography variant="body1" fontWeight="bold">
Likes
</Typography>
<NumberField value={record?.likes} />
<Typography variant="body1" fontWeight="bold">
Favorites
</Typography>
<NumberField value={record?.numberOfFavorites} />
<Typography variant="body1" fontWeight="bold">
Difficulty
</Typography>
<TextField value={record?.difficulty} />
</Stack>
</Show>
);
}
criminal-purple
criminal-purple16mo ago
can you add this to number fields ?
<NumberField value={record?.likes || "-"} />
<NumberField value={record?.numberOfFavorites || "-"} />
<NumberField value={record?.likes || "-"} />
<NumberField value={record?.numberOfFavorites || "-"} />
sorry about that. this is known issue. we will fix this soon when undefined passed to NumberField. its throw error. we will fix soon
extended-salmon
extended-salmon16mo ago
works like a charm! Dont be sorry! You guys are doing an amazing job 😄
flat-fuchsia
flat-fuchsia16mo ago
True!!!
criminal-purple
criminal-purple16mo ago
i'm glad to hear that 🥹 thanks
extended-salmon
extended-salmon16mo ago
this worked as well! 😄