Strapi Admin Panel Customization — Logo, Colors, and Custom Fields
In this tutorial, you will learn how to customize the Strapi admin panel — changing the logo and brand colors, creating custom fields for the Content-Type Builder, and extending the admin interface with custom React components for a branded content management experience.
What You'll Learn
- How to customize the admin panel logo and favicon
- How to change brand colors and typography
- How to create custom fields for the Content-Type Builder
- How to add custom admin panel pages
- How to customize the login page
- How to override admin panel translations
Why It Matters
A white-labeled admin panel provides a professional experience for your content team. Custom fields let you build specialized input interfaces that are better than generic text fields. These customizations turn Strapi from a generic CMS into a tailored content management tool that matches your brand and workflow.
Real-World Use
A digital agency manages 20 client websites, each running Strapi. Each client needs their own branded admin panel. The agency uses admin panel customization to set each client's logo, colors, and login page. Content editors feel like they are using a custom-built CMS, not a generic tool. The agency also builds a custom "Map Location" field that provides a Google Maps picker instead of entering coordinates manually.
Learning Path
flowchart LR A["Custom Plugins"] --> B["Admin Customization
-- You are here"]:::current B --> C["Email & Notifications"] C --> D["Internationalization"] classDef current fill:#4945ff,color:#fff,stroke-width:2px
Logo and Brand Customization
Strapi allows basic branding through the admin panel settings:
// Method 1: Admin panel UI
// Settings > Administration Panel > Admin Panel Settings
// - Upload custom logo (recommended size: 300x80px)
// - Change primary brand color
// - Upload favicon
// Method 2: Configuration file
// src/admin/app.js (Strapi 5)
export default {
config: {
head: {
favicon: "/uploads/logo-favicon.png",
},
auth: {
logo: "/uploads/auth-logo.png", // Login page logo
},
menu: {
logo: "/uploads/menu-logo.png", // Sidebar logo
},
theme: {
colors: {
primary100: "#f0f5ff",
primary200: "#d6e4ff",
primary500: "#4f46e5", // Main brand color
primary600: "#4338ca",
primary700: "#3730a3",
buttonPrimary500: "#4f46e5",
buttonPrimary600: "#4338ca",
},
},
locales: ["en", "fr", "de"],
translations: {
en: {
"app.components.LeftMenu.navbrand.title": "My CMS",
"app.components.LeftMenu.navbrand.workplace": "Content Management",
"Auth.form.welcome.title": "Welcome to My CMS",
"Auth.form.welcome.subtitle": "Log in to manage your content",
},
},
},
};
The logo files should be stored in the public/uploads/ directory or hosted on your CDN.
Custom Login Page
Customize the login page beyond just the logo:
// src/admin/app.js
export default {
config: {
auth: {
logo: "/uploads/custom-logo.png",
},
head: {
favicon: "/uploads/favicon.ico",
},
// Customize the login page background
theme: {
colors: {
// Override login page specific colors
},
},
translations: {
en: {
"Auth.form.email.label": "Work Email",
"Auth.form.password.label": "Password",
"Auth.form.login.title": "Sign in to Dashboard",
"Auth.form.register.title": "Create your account",
},
},
},
};
Custom Fields
Custom fields are reusable input components that appear in the Content-Type Builder and Content Manager.
// src/admin/custom-fields/ColorPicker/index.js
import React from "react";
import { useCMEditViewDataManager } from "@strapi/helper-plugin";
import { Box, Typography, Field } from "@strapi/design-system";
const ColorPicker = ({ name, value, onChange, attribute }) => {
const colors = attribute.options?.colors || [
"#FF0000", "#00FF00", "#0000FF", "#FFFF00", "#FF00FF", "#00FFFF"
];
return (
<Box padding={4}>
<Typography variant="pi" fontWeight="bold">{attribute.customField}</Typography>
<Box padding={2} style={{ display: "flex", gap: "8px", flexWrap: "wrap" }}>
{colors.map((color) => (
<button
key={color}
type="button"
onClick={() => onChange({ target: { name, value: color } })}
style={{
width: 32,
height: 32,
borderRadius: "50%",
backgroundColor: color,
border: value === color ? "3px solid #000" : "2px solid transparent",
cursor: "pointer",
}}
aria-label={`Select color ${color}`}
/>
))}
</Box>
{value && (
<Typography variant="pi" textColor="neutral600">
Selected: {value}
</Typography>
)}
</Box>
);
};
export default ColorPicker;
Register the custom field in a plugin:
// src/plugins/my-custom-fields/admin/src/index.js
import ColorPicker from "./components/ColorPicker";
export default {
register(app) {
app.customFields.register({
name: "color-picker",
pluginId: "my-custom-fields",
type: "string", // Database type
intlLabel: {
id: "my-custom-fields.color-picker.label",
defaultMessage: "Color Picker",
},
intlDescription: {
id: "my-custom-fields.color-picker.description",
defaultMessage: "Select a color from a predefined palette",
},
icon: "paint-brush",
components: {
Input: async () => ColorPicker,
},
options: {
base: [
{
section: "styles",
items: [
{
name: "options.colors",
type: "json",
intlLabel: {
id: "my-custom-fields.color-picker.options.colors",
defaultMessage: "Available colors (JSON array of hex values)",
},
},
],
},
],
},
});
},
};
Adding Custom Admin Pages
Add entirely new pages to the admin panel through plugins:
// admin/src/index.js (in a plugin)
export default {
register(app) {
// Add a page accessible from the main navigation
app.addMenuLink({
to: "/plugins/content-dashboard",
icon: "Dashboard",
intlLabel: {
id: "content-dashboard.plugin.name",
defaultMessage: "Dashboard",
},
Component: async () => {
const component = await import("./pages/Dashboard");
return component;
},
permissions: [],
});
// Add a settings page
app.addSettingsLink({
id: "content-dashboard-settings",
to: "/settings/content-dashboard",
intlLabel: {
id: "content-dashboard.settings",
defaultMessage: "Content Dashboard",
},
Component: async () => {
const component = await import("./pages/Settings");
return component;
},
});
// Inject a component into an existing view
app.injectContentManagerComponent("editView", "right-links", {
name: "publish-history",
Component: async () => {
const component = await import("./components/PublishHistory");
return component;
},
});
},
};
Customizing the Content Manager View
Modify how content types appear in the Content Manager:
// src/admin/extensions/content-manager/index.js
export default {
bootstrap(app) {
// Customize the list view configuration per content type
app.getPlugin("content-manager").apis.configureContentView({
contentType: "api::article.article",
config: {
settings: {
bulkable: true,
filterable: true,
searchable: true,
pageSize: 20,
mainField: "title", // Field shown in list
defaultSortBy: "createdAt",
defaultSortOrder: "DESC",
},
metadatas: {
id: { edit: {}, list: { label: "ID" } },
title: { edit: { label: "Article Title" }, list: { label: "Title" } },
createdAt: { edit: { label: "Created" }, list: { label: "Created" } },
},
layouts: {
list: ["id", "title", "author", "createdAt"],
edit: [
[
{ name: "title", size: 6 },
{ name: "author", size: 6 },
],
[{ name: "content", size: 12 }],
],
},
},
});
},
};
Theme and Styles
Override admin panel styles with custom CSS:
// src/admin/extensions/theme.js
const theme = {
colors: {
primary100: "#eef2ff",
primary200: "#c7d2fe",
primary500: "#6366f1",
primary600: "#4f46e5",
primary700: "#4338ca",
danger100: "#fef2f2",
danger500: "#ef4444",
success100: "#f0fdf4",
success500: "#22c55e",
warning100: "#fffbeb",
warning500: "#f59e0b",
},
shadows: {
popupShadow: "0px 2px 4px rgba(0, 0, 0, 0.1)",
},
sizes: {
borderRadius: "6px",
},
};
export default theme;
Common Mistakes
Using oversized logo images. The admin panel logo should be optimized for web. Large logo files slow down the admin panel load time. Use a PNG or SVG under 50KB.
Customizing too heavily without testing. Aggressive theme changes can break the admin panel layout. Test customizations in development before applying to production.
Not handling custom field edge cases. Custom fields should handle empty values, loading states, and validation errors gracefully. A broken custom field blocks content creation.
Forgetting to rebuild after admin changes. Admin panel customizations require
npm run buildto compile. Changes do not appear until the build is complete.Overriding translations incompletely. If you override some translations but not others, the admin panel shows a mix of custom and default text. Provide complete translation overrides.
Practice Questions
Where do you configure the admin panel logo and colors? Answer: In
src/admin/app.js(Strapi 5) or through the admin panel UI at Settings > Administration Panel > Admin Panel Settings.What is a custom field and how does it differ from a component? Answer: A custom field is a new input type for the Content-Type Builder that provides a specialized editing experience (like a color picker or map selector). A component is a reusable group of fields.
How do you add a custom page to the admin panel? Answer: Through a plugin's
registerfunction usingapp.addMenuLink()to add a navigation item that links to a custom React component page.Challenge: Create a fully branded admin panel: (1) Upload a custom logo and set brand colors, (2) Customize the login page with custom welcome text, (3) Build a custom "Star Rating" field that provides a 1-5 star clickable rating input, (4) Register the custom field in the Content-Type Builder, (5) Create a custom "Content Overview" dashboard page showing recent entries and pending reviews, (6) Test all customizations across different browsers.
FAQ
Mini Project
Your task: Customize Strapi for a branded client experience.
- Set up a branded theme:
- Replace the logo with a custom SVG
- Change the primary color to the brand color (#2563eb)
- Customize the login page title to "Client Content Manager"
- Build a custom "URL Slug" field that:
- Takes a string input
- Shows a preview of the full URL
- Auto-generates from a title field if left empty
- Validates URL-safe characters only
- Add a custom "Content Overview" dashboard page that:
- Shows total entries per content type
- Lists recently modified entries
- Shows entries pending review
- Apply the custom field to one of your content types.
What's Next
Now that you can customize the admin panel, proceed to Email & Notifications to configure the email plugin, send transactional emails, and customize email templates. After that, explore Internationalization for multi-language content.
Related lessons:
- Node.js — How the admin panel React app works
- REST API — Admin panel API endpoints
- WordPress Admin Customization — Compare admin customization
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro