---
title: "Add a Payload Sidebar Logo: Complete 5-Step Quick Guide"
slug: "payload-sidebar-logo-guide"
published: "2026-08-01"
updated: "2026-08-10"
validated: "2026-08-10"
categories:
  - "Payload"
tags:
  - "Payload sidebar logo"
  - "beforeNavLinks"
  - "payload generate:importmap"
  - "Payload admin components"
  - "SidebarLogo component"
  - "Payload multi-tenant logo"
  - "Next.js importMap"
  - "pnpm payload generate:importmap"
  - "React admin components"
  - "admin sidebar branding"
llm-intent: "reference"
audience-level: "intermediate"
framework-versions:
  - "payload cms"
  - "@payloadcms/next"
  - "next.js"
  - "react"
  - "typescript"
status: "stable"
llm-purpose: "Payload sidebar logo: step-by-step guide to add a logo above nav links, register beforeNavLinks, run payload generate:importmap, and enable…"
llm-prereqs:
  - "Access to Payload CMS"
  - "Access to @payloadcms/next"
  - "Access to Next.js"
  - "Access to React"
  - "Access to TypeScript"
llm-outputs:
  - "Completed outcome: Payload sidebar logo: step-by-step guide to add a logo above nav links, register beforeNavLinks, run payload generate:importmap, and enable…"
---

**Summary Triples**
- (Add a Payload Sidebar Logo: Complete 5-Step Quick Guide, focuses-on, Payload sidebar logo: step-by-step guide to add a logo above nav links, register beforeNavLinks, run payload generate:importmap, and enable…)
- (Add a Payload Sidebar Logo: Complete 5-Step Quick Guide, category, general)

### {GOAL}
Payload sidebar logo: step-by-step guide to add a logo above nav links, register beforeNavLinks, run payload generate:importmap, and enable…

### {PREREQS}
- Access to Payload CMS
- Access to @payloadcms/next
- Access to Next.js
- Access to React
- Access to TypeScript

### {STEPS}
1. Choose the beforeNavLinks slot
2. Register component in admin config
3. Write the SidebarLogo component
4. Add admin CSS for sizing
5. Regenerate the import map
6. Verify across views and tenants

<!-- llm:goal="Payload sidebar logo: step-by-step guide to add a logo above nav links, register beforeNavLinks, run payload generate:importmap, and enable…" -->
<!-- llm:prereq="Access to Payload CMS" -->
<!-- llm:prereq="Access to @payloadcms/next" -->
<!-- llm:prereq="Access to Next.js" -->
<!-- llm:prereq="Access to React" -->
<!-- llm:prereq="Access to TypeScript" -->
<!-- llm:output="Completed outcome: Payload sidebar logo: step-by-step guide to add a logo above nav links, register beforeNavLinks, run payload generate:importmap, and enable…" -->

# Add a Payload Sidebar Logo: Complete 5-Step Quick Guide
> Payload sidebar logo: step-by-step guide to add a logo above nav links, register beforeNavLinks, run payload generate:importmap, and enable…
Matija Žiberna · 2026-08-01

Adding a logo above the nav links in Payload's Admin panel means registering a custom component in the `beforeNavLinks` slot, writing a small component that renders your logo, and regenerating the import map so Payload actually picks it up. This guide walks through the full setup, including the one step that trips up most people: forgetting to run `generate:importmap` after adding the component.

I ran into this while setting up multi-tenant branding on a client project, where each tenant needed its own logo in the sidebar instead of one static image. Getting the basic single-logo version working first made the tenant-aware version much easier to reason about, so that's the order this guide follows too.

## Why This Isn't the Same as the Login Logo

Payload's `admin.components.graphics.Logo` and `Icon` options control the login screen and the collapsed-nav icon only. They don't touch the sidebar itself. If you've already set those and you're wondering why your logo isn't showing up above the nav links, that's why. The sidebar needs a separate component, injected through a different slot entirely.

## 1. Pick the Right Injection Slot

Payload's `Nav` component (from `@payloadcms/next`) renders custom components in a fixed order. There's no "insert between X and Y" API, only a set of named slots:

```
NavWrapper
├─ beforeNav        ← above everything, outside the scrollable nav (e.g. multi-tenant's own "Filter by Tenant" selector lives here)
├─ nav.nav__wrap
│  ├─ beforeNavLinks ← top of the scrollable sidebar, above collection/global links
│  ├─ (collection/global links)
│  └─ afterNavLinks  ← below collection/global links, above Logout
├─ settingsMenu       ← inside the gear/settings popup
└─ Nav                 ← replaces the ENTIRE sidebar (last resort)
```

For a logo, `beforeNavLinks` is almost always the slot you want. It sits at the top of the scrollable nav, it already inherits the sidebar's inline padding from `.nav__scroll`, and it doesn't require reimplementing anything Payload already renders for you.

## 2. Register the Component

Point `admin.components.beforeNavLinks` at your component's file path, followed by the named export:

```ts
// File: payload.config.ts
export const adminConfig: Config["admin"] = {
  components: {
    beforeNavLinks: [
      "/path/to/components/SidebarLogo#SidebarLogo",
    ],
  },
  // ...
}
```

Payload resolves this path through a generated import map rather than a direct import. That detail matters for step 4, so keep it in mind.

## 3. Write the Component

A plain `<img>` is enough here unless you specifically need SVG-as-a-React-component behavior. Since the logo is static, either a server or client component works. Make it a client component only once it needs to react to something dynamic, like a selected tenant.

```tsx
// File: src/payload/admin-components/SidebarLogo.tsx
import React from "react";

export function SidebarLogo() {
  return (
    <div className="sidebar-logo">
      {/* eslint-disable-next-line @next/next/no-img-element */}
      <img src="/your-logo.svg" alt="Your Brand" />
    </div>
  );
}

export default SidebarLogo;
```

Add matching CSS through your custom Admin stylesheet. You don't need to hand-roll horizontal padding here, since `.nav__scroll` already applies it to everything inside `beforeNavLinks` and `afterNavLinks`.

```css
/* File: src/app/(payload)/custom.css */
.sidebar-logo {
  margin-bottom: 1.5rem; /* vertical spacing only */
}

.sidebar-logo img {
  display: block;
  height: auto;
  max-width: 160px; /* cap the size so a large source image doesn't blow out the sidebar */
}
```

## 4. Regenerate the Import Map

This is the step people miss. New custom Admin components aren't picked up automatically, even in dev. Payload resolves every `admin.components.*` path through a generated file, `src/app/(payload)/admin/importMap.js` in the Next.js App Router integration. Skip this step and you'll get a runtime error like:

```
getFromImportMap: PayloadComponent not found in importMap
{ key: "/path/to/components/SidebarLogo#SidebarLogo", ... }
"You may need to run the `payload generate:importmap` command..."
```

Run it once after adding, renaming, or moving any custom component:

```bash
pnpm payload generate:importmap
# or: npx payload generate:importmap
```

This rewrites `importMap.js` to import and register your new component. Commit that file. It's generated, but the build depends on it directly, so it needs to stay in version control and stay in sync with your components.

## 5. Verify

Reload the Admin panel and confirm the logo renders above the nav links. Check it across the dashboard, a collection list view, a document edit view, and the collapsed or mobile nav if your project supports one. If the logo doesn't show up, check the browser console before assuming it's a rendering bug. A stale import map is the most common cause.

## Making the Logo Dynamic Per Tenant

Once the static version works, swapping in a per-tenant logo just means replacing the `<img>` with a client component that reads whatever state drives the logo choice. Return `null` when there's nothing to show, so a missing tenant falls back to an empty slot instead of a broken image.

```tsx
// File: src/payload/admin-components/SidebarLogo.tsx
"use client";

export function SidebarLogo() {
  const key = useSomeSelector(); // e.g. useTenantSelection()
  const logo = LOGO_BY_KEY[key];

  if (!logo) return null;

  return (
    <div className="sidebar-logo">
      {/* eslint-disable-next-line @next/next/no-img-element */}
      <img src={logo.src} alt={logo.alt} />
    </div>
  );
}
```

The tenant selection state itself, and the full multi-tenant theming pattern this connects to, are covered in the <a href="./payload-admin-tenant-theming.md">multi-tenant Admin theming guide</a>.

### Worked Example

- Component: `src/payload/admin-components/tenant-theme/TenantSidebarLogo.tsx`
- Registration: `src/payload/config/admin.ts`
- Styles: `src/app/(payload)/custom.css`

## Slot Reference

| Slot | Position | Best for |
|---|---|---|
| `beforeNavLinks` | Top of scrollable nav, above collection/global links | Logo, brand mark, tenant switcher |
| `afterNavLinks` | Bottom of scrollable nav, above Logout | Secondary links, version info, support link |
| `beforeNav` | Outside the scrollable nav entirely | Filters that should stay visible while scrolling, like a tenant selector |
| `Nav` | Replaces the entire sidebar | Full custom nav (you lose everything Payload renders by default) |

## FAQ

**Why isn't my `admin.components.graphics.Logo` setting affecting the sidebar?**
That option only controls the login screen and the collapsed-nav icon. The sidebar logo is a separate component, registered through `beforeNavLinks`.

**Do I need a client component for a static logo?**
No. A server component works fine for a single static logo. Only switch to a client component once the logo needs to respond to state, such as the active tenant.

**What happens if I forget to run `generate:importmap`?**
Payload throws a runtime error saying the component wasn't found in the import map, and the Admin panel won't render your logo. Run `pnpm payload generate:importmap` and reload.

**Should I commit `importMap.js`?**
Yes. It's a generated file, but it's also what the build uses directly, so it has to stay in version control and in sync with your registered components.

**Can I use an SVG file instead of a React component?**
Yes, a plain `<img src="/your-logo.svg">` works the same as any other image format here. Only reach for SVG-as-a-React-component if you need to manipulate the SVG's internals at runtime.

## Wrapping Up

Getting a logo into the Payload Admin sidebar comes down to picking `beforeNavLinks` as the injection slot, writing a small component, and regenerating the import map so Payload's generated registry knows the component exists. The same pattern extends cleanly to a per-tenant logo once you swap the static image for a component that reads tenant state.

Let me know in the comments if you have questions, and subscribe for more practical development guides.

Thanks,
Matija

## LLM Response Snippet
```json
{
  "goal": "Payload sidebar logo: step-by-step guide to add a logo above nav links, register beforeNavLinks, run payload generate:importmap, and enable…",
  "responses": [
    {
      "question": "What does the article \"Add a Payload Sidebar Logo: Complete 5-Step Quick Guide\" cover?",
      "answer": "Payload sidebar logo: step-by-step guide to add a logo above nav links, register beforeNavLinks, run payload generate:importmap, and enable…"
    }
  ]
}
```