> ## Documentation Index
> Fetch the complete documentation index at: https://filamentphp.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Appearance

export const EditOnGitHub = ({version, path}) => {
  const url = `https://github.com/filamentphp/filament/edit/${version}/${path}`;
  return <div className="not-prose mt-16">
      <a href={url} target="_blank" rel="noopener noreferrer" className="inline-flex items-center gap-2 text-sm text-gray-500 transition hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" className="h-4 w-4">
          <path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z" />
        </svg>
        Edit this page on GitHub
      </a>
    </div>;
};

export const Footer = () => {
  const sponsorsByTier = JSON.parse(`{
  "agency_partner": [
    {
      "name": "Kirschbaum",
      "url": "https://kirschbaumdevelopment.com/solutions/filament-development",
      "filename": "kirschbaum.svg"
    }
  ],
  "gold": [
    {
      "name": "Agiledrop",
      "url": "https://www.agiledrop.com/laravel?utm_source=filament",
      "filename": "agiledrop.svg"
    },
    {
      "name": "Baiz.ai",
      "url": "https://baiz.ai",
      "filename": "baiz-ai.svg"
    },
    {
      "name": "CMS Max",
      "url": "https://cmsmax.com?ref=filamentphp.com",
      "filename": "cms-max.svg"
    },
    {
      "name": "Mailtrap",
      "url": "https://mailtrap.io/email-sending?utm_source=community&utm_medium=referral&utm_campaign=filament",
      "filename": "mailtrap.svg"
    },
    {
      "name": "SerpApi",
      "url": "https://serpapi.com/?utm_source=filamentphp",
      "filename": "serpapi.svg"
    }
  ]
}`);
  function shuffleArray(items) {
    const result = [...items];
    for (let index = result.length - 1; index > 0; index--) {
      const randomIndex = Math.floor(Math.random() * (index + 1));
      [result[index], result[randomIndex]] = [result[randomIndex], result[index]];
    }
    return result;
  }
  const sponsors = Object.entries(sponsorsByTier).flatMap(([, sponsors]) => shuffleArray(sponsors));
  return <div className="mt-16 flex flex-col gap-4">
      <h2 className="text-center text-2xl font-medium text-gray-800 dark:text-gray-200">
        Sponsored by
      </h2>

      <div className="not-prose flex flex-wrap items-center justify-center gap-5">
        {sponsors.map(sponsor => <a key={sponsor.name} className="footer-sponsor-card" href={sponsor.url} target="_blank" title={sponsor.name}>
            <img src={`/docs/images/sponsors/footer/${sponsor.filename}`} alt={sponsor.name} noZoom />
            <span className="line-pattern-overlay line-pattern-80" />
          </a>)}

        <a href="https://github.com/sponsors/danharrin" target="_blank" className="footer-sponsor-cta">
          <span className="sponsor-cta-content">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
              <path d="M5 12h14" />
              <path d="M12 5v14" />
            </svg>
            <span>Your logo here</span>
          </span>
          <span className="line-pattern-overlay line-pattern-60" />
        </a>
      </div>
    </div>;
};

## Changing the brand logo

By default, Filament will use your app's name as a brand logo in the admin panel.

You may create a `resources/views/vendor/filament/components/brand.blade.php` file to provide a custom logo:

```blade theme={"theme":"gruvbox-dark-hard"}
<img src="{{ asset('/images/logo.svg') }}" alt="Logo" class="h-10">
```

## Dark mode

By default, Filament only includes a light theme. However, you may allow the user to switch to dark mode if they wish, using the `dark_mode` setting of the [configuration file](./installation#publishing-configuration):

```php theme={"theme":"gruvbox-dark-hard"}
'dark_mode' => true,
```

When dark mode is enabled, the admin panel will automatically obey your system's dark / light mode preference. You may switch to dark / light mode permanently through the button in the user dropdown menu.

If you're using a [custom theme](#building-themes), make sure that you have the `darkMode: 'class'` setting in your `tailwind.config.js` file.

> Please note: before enabling dark mode in production, please thoroughly test your admin panel - especially third party plugins, which may not be properly tested with dark mode.

When the user toggles between dark or light mode, a browser event called **dark-mode-toggled** is dispatched. You can listen to it:

```html theme={"theme":"gruvbox-dark-hard"}
<div
    x-data="{ mode: 'light' }"
    x-on:dark-mode-toggled.window="mode = $event.detail"
>
    <span x-show="mode === 'light'">
        Light mode
    </span>

    <span x-show="mode === 'dark'">
        Dark mode
    </span>
</div>
```

## Collapsible sidebar

By default, the sidebar is only collapsible on mobile. You may make it collapsible on desktop as well.

You must [publish the configuration](./installation#publishing-configuration) in order to access this feature.

In `config/filament.php`, set the `layout.sidebar.is_collapsible_on_desktop` to `true`:

```php theme={"theme":"gruvbox-dark-hard"}
'layout' => [
    'sidebar' => [
        'is_collapsible_on_desktop' => true,
    ],
],
```

## Non-sticky topbar

By default, the topbar sticks to the top of the page.

You may make the topbar scroll out of view instead by adding the following styles to your [theme](#building-themes) or by [registering a new stylesheet](#including-frontend-assets):

```css theme={"theme":"gruvbox-dark-hard"}
.filament-main-topbar {
    position: relative;
}
```

## Building themes

Filament allows you to change the fonts and color scheme used in the UI, by compiling a custom stylesheet to replace the default one. This custom stylesheet is called a "theme".

Themes use [Tailwind CSS](https://tailwindcss.com), the Tailwind Forms plugin, and the Tailwind Typography plugin, [Autoprefixer](https://github.com/postcss/autoprefixer), and [Tippy.js](https://atomiks.github.io/tippyjs/). You may install these through NPM:

```bash theme={"theme":"gruvbox-dark-hard"}
npm install tailwindcss @tailwindcss/forms @tailwindcss/typography autoprefixer tippy.js --save-dev
```

To finish installing Tailwind, you must create a new `tailwind.config.js` file in the root of your project. The easiest way to do this is by running `npx tailwindcss init`.

In `tailwind.config.js`, register the plugins you installed, and add custom colors used by the form builder:

```js theme={"theme":"gruvbox-dark-hard"}
import colors from 'tailwindcss/colors'
import forms from '@tailwindcss/forms'
import typography from '@tailwindcss/typography'


export default {
    content: [
        './resources/**/*.blade.php',
        './vendor/filament/**/*.blade.php',
    ],
    darkMode: 'class',
    theme: {
        extend: {
            colors: {
                danger: colors.rose,
                primary: colors.blue,
                success: colors.green,
                warning: colors.yellow,
            },
        },
    },
    plugins: [
        forms,
        typography,
    ],
}
```

You may specify your own colors, which will be used throughout the admin panel.

If you use Vite to compile assets, in your `vite.config.js` file, register the `filament.css` theme file:

```js theme={"theme":"gruvbox-dark-hard"}
import { defineConfig } from 'vite'

import laravel from 'laravel-vite-plugin'


<Warning>
You are currently viewing the documentation for Filament 2.x, which is a previous version of Filament.

Looking for the current stable version? Visit the [5.x documentation](/5.x).
</Warning>

export default defineConfig({
    plugins: [
        laravel({
            input: [
                // ...
                'resources/css/filament.css',
            ],
            // ...
        }),
    ],
})
```

And add Tailwind to the `postcss.config.js` file:

```js theme={"theme":"gruvbox-dark-hard"}
export default {
    plugins: {
        tailwindcss: {},
        autoprefixer: {},
    },
}
```

Or if you're using Laravel Mix instead of Vite, in your `webpack.mix.js` file, register Tailwind CSS as a PostCSS plugin:

```js theme={"theme":"gruvbox-dark-hard"}
const mix = require('laravel-mix')

mix.postCss('resources/css/filament.css', 'public/css', [
    require('tailwindcss'),
])
```

In `/resources/css/filament.css`, import Filament's vendor CSS:

```css theme={"theme":"gruvbox-dark-hard"}
@import '../../vendor/filament/filament/resources/css/app.css';
```

Now, you may register the theme file in a service provider's `boot()` method:

```php theme={"theme":"gruvbox-dark-hard"}
use Filament\Facades\Filament;

Filament::serving(function () {
    // Using Vite
    Filament::registerViteTheme('resources/css/filament.css');

    // Using Laravel Mix
    Filament::registerTheme(
        mix('css/filament.css'),
    );
});
```

### Loading Google Fonts

If you specify a custom font family in your `tailwind.config.js`, you may wish to import it via Google Fonts.

You must [publish the configuration](./installation#publishing-configuration) in order to access this feature.

Set the `google_fonts` config option to a new Google Fonts URL to load:

```php theme={"theme":"gruvbox-dark-hard"}
'google_fonts' => 'https://fonts.googleapis.com/css2?family=Inter:ital,wght@0,400;0,500;0,700;1,400;1,500;1,700&display=swap',
```

## Changing the maximum content width

Filament exposes a configuration option that allows you to change the maximum content width of all pages.

You must [publish the configuration](./installation#publishing-configuration) in order to access this feature.

In `config/filament.php`, set the `layout.max_content_width` to any value between `xl` and `7xl`, or `full` for no max width:

```php theme={"theme":"gruvbox-dark-hard"}
'layout' => [
    'max_content_width' => 'full',
],
```

The default is `7xl`.

You may override the maximum content width for a specific page in the admin panel by using the `$maxContentWidth` property:

```php theme={"theme":"gruvbox-dark-hard"}
protected ?string $maxContentWidth = 'full';
```

## Including frontend assets

You may register your own scripts and styles using the `registerScripts()` and `registerStyles()` methods in a service provider's `boot()` method:

```php theme={"theme":"gruvbox-dark-hard"}
use Filament\Facades\Filament;

Filament::registerScripts([
    asset('js/my-script.js'),
]);

Filament::registerStyles([
    'https://unpkg.com/tippy.js@6/dist/tippy.css',
    asset('css/my-styles.css'),
]);
```

You may pass `true` as a parameter to `registerScripts()` to load it before Filament's core JavaScript. This is useful for registering Alpine.js plugins from a CDN:

```php theme={"theme":"gruvbox-dark-hard"}
Filament::registerScripts([
    'https://cdn.jsdelivr.net/npm/@ryangjchandler/alpine-tooltip@0.x.x/dist/cdn.min.js',
], true);
```

## Custom meta tags

You can add custom tags to the header, such as `<meta>` and `<link>`, using the following:

```php theme={"theme":"gruvbox-dark-hard"}
use Filament\Facades\Filament;
use Illuminate\Support\HtmlString;

Filament::pushMeta([
    new HtmlString('<link rel="manifest" href="/site.webmanifest" />'),
]);
```

## Notification position

Filament allows you to customize the position of notifications.

In `config/filament.php`, set the `layout.notifications.alignment` to any value of `left`, `center` or `right` and `layout.notifications.vertical_alignment` to any value of `top`, `center` or `bottom`:

```php theme={"theme":"gruvbox-dark-hard"}
'layout' => [
    'notifications' => [
        'vertical_alignment' => 'top',
        'alignment' => 'center',
    ],
],
```

## Render hooks

Filament allows you to render Blade content at various points in the admin panel layout. This is useful for integrations with packages like [`wire-elements/modal`](https://github.com/wire-elements/modal) which require you to add a Livewire component to your app.

Here's an example, integrating [`wire-elements/modal`](https://github.com/wire-elements/modal) with Filament in a service provider:

```php theme={"theme":"gruvbox-dark-hard"}
use Filament\Facades\Filament;
use Illuminate\Support\Facades\Blade;

Filament::registerRenderHook(
    'body.start',
    fn (): string => Blade::render('@livewire(\'livewire-ui-modal\')'),
);
```

You could also render view content from a file:

```php theme={"theme":"gruvbox-dark-hard"}
use Filament\Facades\Filament;
use Illuminate\Contracts\View\View;

Filament::registerRenderHook(
    'body.start',
    fn (): View => view('impersonation-banner'),
);
```

The available hooks are as follows:

* `body.start` - after `<body>`
* `body.end` - before `</body>`
* `head.start` - after `<head>`
* `head.end` - before `</head>`
* `content.start` - before page content
* `content.end` - after page content
* `footer.before` - before footer
* `footer.start` - start of footer content (centered)
* `footer.end` - end of footer content (centered)
* `footer.after` - after footer
* `sidebar.start` - before [sidebar](./navigation) content
* `sidebar.end` - after [sidebar](./navigation) content
* `scripts.start` - before scripts are defined
* `scripts.end` - after scripts are defined
* `styles.start` - before styles are defined
* `styles.end` - after styles are defined
* `global-search.start` - before [global search](./resources/global-search) input
* `global-search.end` - after [global search](./resources/global-search) input
* `user-menu.start` - before [user menu](./navigation#customizing-the-user-menu) input
* `user-menu.end` - after [user menu](./navigation#customizing-the-user-menu) input
* `user-menu.account.before` - before the account item in the [user menu](./navigation#customizing-the-user-menu)
* `user-menu.account.after` - after the account item in the [user menu](./navigation#customizing-the-user-menu)
* `page.header-widgets.start` - before page header widgets
* `page.header-widgets.end` - after page header widgets
* `page.footer-widgets.start` - before page footer widgets
* `page.footer-widgets.end` - after page footer widgets
* `page.actions.start` - before page actions
* `page.actions.end` - after page actions
* `resource.pages.list-records.table.start` - before the resource table
* `resource.pages.list-records.table.end` - after the resource table
* `resource.relation-manager.start` - before the relation manager table
* `resource.relation-manager.end` - after the relation manager table

<EditOnGitHub version="2.x" path="packages/admin/docs/08-appearance.md" />

<Footer />
