Is there a way to customize Logo/Icons?

Hi everyone,

I am running a self-hosted instance of Vaultwarden (v2025.12.1) using CasaOS.

I want to customize the branding of my site for personal use (replace the default logo and favicons with my own assets).

My question is: What is the standard, persistent way to implement custom branding (logos/icons)? Is there a specific volume mapping strategy or configuration I should use to override the web-vault images properly so they stick?

Thanks for your help!

Some SVGs are compiled into the web-vault, so they are not easy to replace. You can use CSS to use custom images instead:

I would mount the images into /web-vault/images so Vaultwarden can serve them as assets (and also to override the images that do get served from that directory).

The Issue: When I load the login page, my custom logo appears for a split second, but then the page refreshes/renders fully, and the default Vaultwarden logo takes over again. The custom styling seems to be applied initially but gets overridden or ignored after the specific page components initialize.

My Setup:

  • Deployment: Docker (via CasaOS)

  • Environment Variable: TEMPLATES_FOLDER=/data/templates

  • Volumes:

    • Host: /DATA/.../vaultwarden/data mapped to Container: /data

    • Host: /DATA/.../Logos/SVG mapped to Container: /web-vault/images/custom

Verification:

  • I have verified that the image URL is accessible. Browsing to https://my-vault-url/images/custom/Trueguard_Logo.svg loads the image correctly.

  • I have set permissions to 777 on the templates folder to rule out permission issues.

  • The TEMPLATES_FOLDER is pointing to the correct location inside the container (/data/templates), which maps to the host folder containing the scss subdirectory.

Current user.vaultwarden.scss.hbs content:

 /DATA/AppData/vaultwarden/data/templates/scss/user.vaultwarden.scss.hbs
                             
/* Use a custom login logo */
app-root img.new-logo-themed {
    content: url('/images/custom/Trueguard_Logo.svg') !important;
    width: 250px !important;
    height: auto !important;
}

/* Use a custom top left logo on login and locked screen page */
auth-anon-layout > main > a > bit-icon > svg {
  display: none !important;
}
auth-anon-layout > main > a > bit-icon::before {
  display: block;
  content: "" !important;
  width: 200px !important;
  height: 150px !important;
  background-image: url('/images/custom/Trueguard_Logo.svg') !important;
  background-repeat: no-repeat !important;
  background-size: contain;
  background-position: center;
}



/* (Sidebar - Vault & Admin) */
app-user-layout bit-nav-logo bit-icon > svg,
app-organization-layout bit-nav-logo bit-icon > svg {
  display: none !important;
}

app-user-layout bit-nav-logo bit-icon::before,
app-organization-layout bit-nav-logo bit-icon::before {
  display: block;
  content: "" !important;
  width: 220px !important;
  height: 50px !important;
  background-repeat: no-repeat !important;
  background-size: contain;
  background-position: center left;
}


app-user-layout bit-nav-logo bit-icon::before {
  background-image: url('/images/custom/Trueguard_withPW.svg') !important;
}
app-organization-layout bit-nav-logo bit-icon::before {
  background-image: url('/images/custom/Trueguard_withPW.svg') !important;
}

Question (@stefan0xC): Since you helped me previously: I believe I have set up the paths correctly now as the images are loading via direct URL. However, have you experienced this “flashing” behavior where the custom logo is visible for a moment and then disappears?

Is there a more specific CSS selector I should be using for the current version of the web-vault to ensure the custom logo stays persistent and isn’t overridden by the JS rendering?

Any advice is appreciated!

Seems like the new web-vault added a div between main and a. So either use auth-anon-layout > main a > bit-icon or auth-anon-layout > main > div > a > bit-icon. (As far as I’ve checked that’s currently the only linked bit-icon on the login page so the less specific one should not affect anything it shouldn’t either.)

/* --- CUSTOM BRANDING SETUP --- */

/* 1. LOGIN LOGO - IMAGE TAG REPLACEMENT */
/* Targeted per default instructions */
app-root img.new-logo-themed,
img[src*="logo"],
img[src*="icon"] {
    content: url('/images/custom/Trueguard_Logo.svg') !important;
    width: 250px !important;
    height: auto !important;
    max-height: 150px !important;
}

/* 2. LOGIN SVG ICON REPLACEMENT (THE ISSUE) */

/* * ATTEMPT 1: Original structure
 * auth-anon-layout > main > a > bit-icon
 */

/* * ATTEMPT 2: Based on @stefan0xC suggestion (Added > div >)
 * We tried this, but the logo flashes for 0.5s and then reverts to default.
 */
auth-anon-layout > main > div > a > bit-icon > svg {
  display: none !important;
}

auth-anon-layout > main > div > a > bit-icon::before {
  display: block !important;
  content: "" !important;
  width: 250px !important;
  height: 150px !important;
  background-image: url('/images/custom/Trueguard_Logo.svg') !important;
  background-repeat: no-repeat !important;
  background-size: contain !important;
  background-position: center !important;
  margin-bottom: 20px !important;
}

/* * ATTEMPT 3: Loose selector (Space instead of >)
 * auth-anon-layout main bit-icon::before
 * Result: Same flashing behavior.
 */


/* 3. SIDEBAR LOGOS (Post-login) */
/* These are working correctly */
app-user-layout bit-nav-logo bit-icon > svg,
app-organization-layout bit-nav-logo bit-icon > svg {
  display: none !important;
}

app-user-layout bit-nav-logo bit-icon::before,
app-organization-layout bit-nav-logo bit-icon::before {
  display: block;
  content: "" !important;
  width: 220px !important;
  height: 60px !important;
  background-image: url('/images/custom/Trueguard_withPW.svg') !important;
  background-repeat: no-repeat !important;
  background-size: contain;
  background-position: center left;
}

Thanks for the suggestion regarding the extra div!

I have updated my SCSS file to reflect the structure you mentioned (auth-anon-layout > main > div > a > bit-icon), but unfortunately, I am still experiencing the “flashing” behavior.

The behavior:

  1. I refresh the login page (Ctrl+F5 / Incognito).

  2. My Custom Logo appears correctly for about 0.5 seconds.

  3. The page finishes rendering, and it reverts back to the default Vaultwarden safe logo.

Do you have any idea how to make it permanent?
Thank you!

Can you load the page in the devloper console and check if the /css/vaultwarden.css has actually refreshed by loading the page without cache?

Hello ! I have the exact same problem as @gilgameshun, any news ? :slight_smile:

What news are you expecting? Have you checked the css file if it is correctly loaded?

I don’t experience the described flashing/reverting to the original image because with the following rule the existing image in the top left should not be displayed anymore (even if the image would fail to load):

auth-anon-layout > main > div > a > bit-icon > svg {
  display: none !important;
}

Peek 2026-01-06 18-50