[GH-ISSUE #3538] Add a dark mode #2351

Open
opened 2026-02-26 07:35:12 +03:00 by kerem · 16 comments
Owner

Originally created by @Cocolin67 on GitHub (Feb 10, 2024).
Original GitHub issue: https://github.com/NginxProxyManager/nginx-proxy-manager/issues/3538

Maybe just add a toggle that can switch the theme to dark, since it use Tabler, i guess it should be easy to create that ! My eyes would be pleased thanks, love the proxy manager :)

Originally created by @Cocolin67 on GitHub (Feb 10, 2024). Original GitHub issue: https://github.com/NginxProxyManager/nginx-proxy-manager/issues/3538 Maybe just add a toggle that can switch the theme to dark, since it use Tabler, i guess it should be easy to create that ! My eyes would be pleased thanks, love the proxy manager :)
Author
Owner

@Cocolin67 commented on GitHub (Feb 13, 2024):

Oh thanks, I didn't see it

<!-- gh-comment-id:1940904314 --> @Cocolin67 commented on GitHub (Feb 13, 2024): Oh thanks, I didn't see it
Author
Owner

@EthyMoney commented on GitHub (Feb 19, 2024):

That's just for the docs though right? Is there anything in the works for the app UI itself?

<!-- gh-comment-id:1952595717 --> @EthyMoney commented on GitHub (Feb 19, 2024): That's just for the docs though right? Is there anything in the works for the app UI itself?
Author
Owner

@wchorski commented on GitHub (Feb 22, 2024):

I have a work around if you're willing to do a bit of css override

here is my blog post about it, but I'll try to give you the short version here

Run the container

spin up the container first and let the app pull down.

Map the CSS volume

now map `/app/frontend/css/main.css' as a volume to your local machine so that your dark mode tweak persists.

version: '3.8'
services:
  app:
    image: 'jc21/nginx-proxy-manager:latest'
    restart: unless-stopped
    ports:
      - '80:80'
      - '81:81'
      - '443:443'
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
      - ./css/main.css:/app/frontend/css/main.css

spin up the container again and go to edit that new ./css/main.css file

CSS

here is what I've added at the bottom of that css file. It isn't perfect but I kinda like the plumb color theme

body, .modal-content{
  background-color: #635366;
  color: white;
 }

 .modal-content{
  box-shadow: black 2px 2px 8px;
 }

 .custom-switch-description{
    color: #c3c3c3;
  }

 #header{
  background-color: #323232;
 }
 .navbar-light .navbar-brand{
  color: white;
 }
 #menu{
  background-color: #000;
 }

 .text-default {
    color: white !important;
  }

  .tag{
    background-color: #545454;
    color: white;
  }

 .card{
    background-color: #29292a;
    box-shadow: black 2px 2px 8px;
  }

  .table thead {
    border-bottom: solid black 3px;
  }
  .table th, .text-wrap table th, .table td, .text-wrap table td{
    border-top: 1px solid #000000;
    border-top-width: 1px;
    border-top-style: solid;
    border-top-color: rgb(0, 0, 0);
  }
<!-- gh-comment-id:1960331080 --> @wchorski commented on GitHub (Feb 22, 2024): I have a work around if you're willing to do a bit of css override here is my [blog post](https://pywrite-garden.tawtaw.site/developer/Home%20Lab%20%F0%9F%8F%A0/Nginx%20Proxy%20Manager#dark-mode) about it, but I'll try to give you the short version here ## Run the container spin up the container first and let the app pull down. ## Map the CSS volume now map `/app/frontend/css/main.css' as a volume to your local machine so that your **dark mode** tweak persists. ```yml version: '3.8' services: app: image: 'jc21/nginx-proxy-manager:latest' restart: unless-stopped ports: - '80:80' - '81:81' - '443:443' volumes: - ./data:/data - ./letsencrypt:/etc/letsencrypt - ./css/main.css:/app/frontend/css/main.css ``` spin up the container again and go to edit that new `./css/main.css` file ## CSS here is what I've added at the bottom of that css file. It isn't perfect but I kinda like the plumb color theme ```css body, .modal-content{ background-color: #635366; color: white; } .modal-content{ box-shadow: black 2px 2px 8px; } .custom-switch-description{ color: #c3c3c3; } #header{ background-color: #323232; } .navbar-light .navbar-brand{ color: white; } #menu{ background-color: #000; } .text-default { color: white !important; } .tag{ background-color: #545454; color: white; } .card{ background-color: #29292a; box-shadow: black 2px 2px 8px; } .table thead { border-bottom: solid black 3px; } .table th, .text-wrap table th, .table td, .text-wrap table td{ border-top: 1px solid #000000; border-top-width: 1px; border-top-style: solid; border-top-color: rgb(0, 0, 0); } ```
Author
Owner

@Cocolin67 commented on GitHub (Apr 18, 2024):

#3395

Resolved since update is released

<!-- gh-comment-id:2064224933 --> @Cocolin67 commented on GitHub (Apr 18, 2024): > #3395 Resolved since update is released
Author
Owner

@jpeaglesandkatz commented on GitHub (May 21, 2024):

why is this closed when the initial issues was opend regarding dark mod in the proxy manager UI itself, NOT the documentation...

It is outright silly that a project like nginx proxy manager doesn't include darkmode.. Especially when apparently it is using an easy theming solution.

<!-- gh-comment-id:2122026690 --> @jpeaglesandkatz commented on GitHub (May 21, 2024): why is this closed when the initial issues was opend regarding dark mod in the proxy manager UI itself, NOT the documentation... It is outright silly that a project like nginx proxy manager doesn't include darkmode.. Especially when apparently it is using an easy theming solution.
Author
Owner

@ramphex commented on GitHub (Jun 29, 2024):

is there any update on this? Why did the docs get themed but the the actual dashboard UI?

<!-- gh-comment-id:2198287235 --> @ramphex commented on GitHub (Jun 29, 2024): is there any update on this? Why did the docs get themed but the the actual dashboard UI?
Author
Owner

@Cocolin67 commented on GitHub (Jul 31, 2024):

Apparently it's still not fixed, i thought it was but it was just the doc that got the dark UI. i'll reopen the issue

<!-- gh-comment-id:2260245032 --> @Cocolin67 commented on GitHub (Jul 31, 2024): Apparently it's still not fixed, i thought it was but it was just the doc that got the dark UI. i'll reopen the issue
Author
Owner

@drummerwolli commented on GitHub (Aug 19, 2024):

sounds like a duplicate of https://github.com/NginxProxyManager/nginx-proxy-manager/issues/707

<!-- gh-comment-id:2296045699 --> @drummerwolli commented on GitHub (Aug 19, 2024): sounds like a duplicate of https://github.com/NginxProxyManager/nginx-proxy-manager/issues/707
Author
Owner

@RobLoach commented on GitHub (Jan 29, 2025):

Duplicate of https://github.com/NginxProxyManager/nginx-proxy-manager/issues/4314 too .

<!-- gh-comment-id:2623027684 --> @RobLoach commented on GitHub (Jan 29, 2025): Duplicate of https://github.com/NginxProxyManager/nginx-proxy-manager/issues/4314 too .
Author
Owner

@HybridRCG commented on GitHub (Apr 4, 2025):

The funny thing is , NPM's own website - "https://nginxproxymanager.com/" does have a toggle for dark mode..
Only reason why i'm not changing to another reverse proxy manager just for the dark mode sake is that I don't have to go into NPM very often. but sure as makes my eyes hurt every time i have to use it. :(

I see the workaround. but the fare question is why must a different service be running purely for dark mode?

<!-- gh-comment-id:2779188426 --> @HybridRCG commented on GitHub (Apr 4, 2025): The funny thing is , NPM's own website - "https://nginxproxymanager.com/" does have a toggle for dark mode.. Only reason why i'm not changing to another reverse proxy manager just for the dark mode sake is that I don't have to go into NPM very often. but sure as makes my eyes hurt every time i have to use it. :( I see the workaround. but the fare question is why must a different service be running purely for dark mode?
Author
Owner

@vacerde commented on GitHub (May 2, 2025):

Any updates on this?

<!-- gh-comment-id:2848115590 --> @vacerde commented on GitHub (May 2, 2025): Any updates on this?
Author
Owner

@RobLoach commented on GitHub (May 2, 2025):

Click the "Subscribe" button if you'd like to be notified of any updates in this issue?

<!-- gh-comment-id:2848197806 --> @RobLoach commented on GitHub (May 2, 2025): Click the "Subscribe" button if you'd like to be notified of any updates in this issue?
Author
Owner

@reynold-lariza commented on GitHub (Jul 14, 2025):

If anyone couldn't find what @wchorski anymore. I generated this dark mode with ChatGPT.

Just apply at the last line of main.css

Tried to fight with ChatGPT for 30 mins to make it look nice, but there are still some hiccups, like the unselected radio buttons in Settings > Custom page > Edit looks invisible, and the file browse button looks contrasting. But I rarely look at these pages anyway, so I had to settle with this one.


/* General navbar and user info */
.navbar-brand,
.navbar-text,
.user-name,
.user-role {
  color: #f5f5f5 !important;
}

/* Sidebar and header links */
.nav-link,
.nav-link:hover {
  color: #e0e0e0 !important;
}

/* Inputs, Selects, and Textareas */
input,
select,
textarea {
  border-color: #555 !important;
  background-color: #1e1e1e !important;
  color: #e0e0e0 !important;
}

input:focus,
select:focus,
textarea:focus {
  outline: 1px solid #888 !important;
}

/* Button tweaks */
.btn-outline-primary {
  color: #a4c6ff !important;
  border-color: #a4c6ff !important;
}

/* Selectize Integration Fixes */
.selectize-input {
  background-color: #1e1e1e !important;
  color: #e0e0e0 !important;
  border: 1px solid #444 !important;
}

.selectize-dropdown,
.selectize-dropdown-content {
  background-color: #2a2a2a !important;
  color: #dcdcdc !important;
  border: 1px solid #444 !important;
}

.selectize-dropdown .active {
  background-color: #3a3a3a !important;
  color: #ffffff !important;
  font-weight: 500 !important;
}

/* Fallback for other dropdowns */
.dropdown-menu,
.dropdown-item,
select option {
  background-color: #2b2b2b !important;
  color: #dcdcdc !important;
}

.dropdown-item:hover,
.dropdown-item:focus,
.dropdown-item.active,
select option:hover,
select option:checked {
  background-color: #3a3a3a !important;
  color: #ffffff !important;
  font-weight: bold;
}



/* Fix invisible select (dropdowns styled as radio buttons) */
input[type="radio"] + label,
input[type="checkbox"] + label {
  color: #e0e0e0 !important;
}

/* Fix text area border and background */
textarea,
textarea.form-control,
.textarea,
.form-control {
  background-color: #1e1e1e !important;
  color: #e0e0e0 !important;
  border: 1px solid #555 !important;
}

/* Improve contrast of label elements */
label {
  color: #ccc !important;
}



/* Native radio button styling for dark mode */
input[type="radio"] {
  appearance: none;
  -webkit-appearance: none;
  background-color: #1e1e1e !important;
  border: 2px solid #666 !important;
  border-radius: 50%;
  width: 16px;
  height: 16px;
  position: relative;
  display: inline-block;
  vertical-align: middle;
  margin-right: 6px;
  transition: border-color 0.2s ease-in-out, background-color 0.2s ease-in-out;
}

input[type="radio"]:checked::after {
  content: '';
  position: absolute;
  top: 4px;
  left: 4px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background-color: #4fc3f7;
  display: block;
}

/* Align label and maintain contrast */
input[type="radio"] + label {
  color: #ccc !important;
  cursor: pointer;
}



/* Fix radio alignment and visibility */
input[type="radio"] {
  appearance: auto !important; /* revert to native look */
  -webkit-appearance: radio !important;
  background-color: #1e1e1e !important;
  border: 1px solid #777 !important;
  margin-right: 8px;
  vertical-align: middle;
}

/* Ensure label stays inline with radio */
input[type="radio"] + label {
  display: inline-block !important;
  vertical-align: middle;
  margin-bottom: 0 !important;
  color: #ccc !important;
}



/* --- FINAL FIXES --- */

/* Force radio + label on same line */
.radio,
input[type="radio"] {
  display: inline-block !important;
  vertical-align: middle !important;
  margin: 0 8px 0 0 !important;
}

input[type="radio"] + label {
  display: inline-block !important;
  vertical-align: middle !important;
  margin: 0 !important;
  padding-left: 4px;
  color: #ccc !important;
}

/* File input styling */
input[type="file"] {
  background-color: #1e1e1e !important;
  color: #ccc !important;
  border: 1px solid #555 !important;
  padding: 6px 12px;
}

/* File upload Browse button */
input[type="file"]::-webkit-file-upload-button {
  background-color: #333 !important;
  color: #eee !important;
  border: 1px solid #666 !important;
  padding: 6px 12px;
  cursor: pointer;
}

input[type="file"]::-webkit-file-upload-button:hover {
  background-color: #444 !important;
  color: #fff !important;
}



/* --- Final Radio Icon Alignment & Spacing Fix --- */
.custom-control {
  padding-left: 0 !important;
  margin-bottom: 0.5rem !important;
}

.custom-control-input {
  display: none !important; /* hide native input */
}

.custom-control-label {
  display: inline-block !important;
  margin: 0 !important;
  color: #ccc !important;
  vertical-align: middle !important;
  padding: 0 !important;
}

.custom-control .feather {
  display: inline-block !important;
  vertical-align: middle !important;
  margin-right: 0.5rem !important;
  width: 1rem !important;
  height: 1rem !important;
  stroke-width: 2 !important;
}

/* Unselected (circle) */
.custom-control .feather[data-icon="circle"] {
  stroke: #868e96 !important;
  fill: none !important;
}

/* Selected (disc) */
.custom-control .feather[data-icon="disc"] {
  stroke: #4fc3f7 !important;
  fill: #4fc3f7 !important;
}
<!-- gh-comment-id:3067858470 --> @reynold-lariza commented on GitHub (Jul 14, 2025): If anyone couldn't find what @wchorski anymore. I generated this dark mode with ChatGPT. Just apply at the last line of `main.css` Tried to fight with ChatGPT for 30 mins to make it look nice, but there are still some hiccups, like the unselected radio buttons in Settings > Custom page > Edit looks invisible, and the file browse button looks contrasting. But I rarely look at these pages anyway, so I had to settle with this one. ```css /* General navbar and user info */ .navbar-brand, .navbar-text, .user-name, .user-role { color: #f5f5f5 !important; } /* Sidebar and header links */ .nav-link, .nav-link:hover { color: #e0e0e0 !important; } /* Inputs, Selects, and Textareas */ input, select, textarea { border-color: #555 !important; background-color: #1e1e1e !important; color: #e0e0e0 !important; } input:focus, select:focus, textarea:focus { outline: 1px solid #888 !important; } /* Button tweaks */ .btn-outline-primary { color: #a4c6ff !important; border-color: #a4c6ff !important; } /* Selectize Integration Fixes */ .selectize-input { background-color: #1e1e1e !important; color: #e0e0e0 !important; border: 1px solid #444 !important; } .selectize-dropdown, .selectize-dropdown-content { background-color: #2a2a2a !important; color: #dcdcdc !important; border: 1px solid #444 !important; } .selectize-dropdown .active { background-color: #3a3a3a !important; color: #ffffff !important; font-weight: 500 !important; } /* Fallback for other dropdowns */ .dropdown-menu, .dropdown-item, select option { background-color: #2b2b2b !important; color: #dcdcdc !important; } .dropdown-item:hover, .dropdown-item:focus, .dropdown-item.active, select option:hover, select option:checked { background-color: #3a3a3a !important; color: #ffffff !important; font-weight: bold; } /* Fix invisible select (dropdowns styled as radio buttons) */ input[type="radio"] + label, input[type="checkbox"] + label { color: #e0e0e0 !important; } /* Fix text area border and background */ textarea, textarea.form-control, .textarea, .form-control { background-color: #1e1e1e !important; color: #e0e0e0 !important; border: 1px solid #555 !important; } /* Improve contrast of label elements */ label { color: #ccc !important; } /* Native radio button styling for dark mode */ input[type="radio"] { appearance: none; -webkit-appearance: none; background-color: #1e1e1e !important; border: 2px solid #666 !important; border-radius: 50%; width: 16px; height: 16px; position: relative; display: inline-block; vertical-align: middle; margin-right: 6px; transition: border-color 0.2s ease-in-out, background-color 0.2s ease-in-out; } input[type="radio"]:checked::after { content: ''; position: absolute; top: 4px; left: 4px; width: 6px; height: 6px; border-radius: 50%; background-color: #4fc3f7; display: block; } /* Align label and maintain contrast */ input[type="radio"] + label { color: #ccc !important; cursor: pointer; } /* Fix radio alignment and visibility */ input[type="radio"] { appearance: auto !important; /* revert to native look */ -webkit-appearance: radio !important; background-color: #1e1e1e !important; border: 1px solid #777 !important; margin-right: 8px; vertical-align: middle; } /* Ensure label stays inline with radio */ input[type="radio"] + label { display: inline-block !important; vertical-align: middle; margin-bottom: 0 !important; color: #ccc !important; } /* --- FINAL FIXES --- */ /* Force radio + label on same line */ .radio, input[type="radio"] { display: inline-block !important; vertical-align: middle !important; margin: 0 8px 0 0 !important; } input[type="radio"] + label { display: inline-block !important; vertical-align: middle !important; margin: 0 !important; padding-left: 4px; color: #ccc !important; } /* File input styling */ input[type="file"] { background-color: #1e1e1e !important; color: #ccc !important; border: 1px solid #555 !important; padding: 6px 12px; } /* File upload Browse button */ input[type="file"]::-webkit-file-upload-button { background-color: #333 !important; color: #eee !important; border: 1px solid #666 !important; padding: 6px 12px; cursor: pointer; } input[type="file"]::-webkit-file-upload-button:hover { background-color: #444 !important; color: #fff !important; } /* --- Final Radio Icon Alignment & Spacing Fix --- */ .custom-control { padding-left: 0 !important; margin-bottom: 0.5rem !important; } .custom-control-input { display: none !important; /* hide native input */ } .custom-control-label { display: inline-block !important; margin: 0 !important; color: #ccc !important; vertical-align: middle !important; padding: 0 !important; } .custom-control .feather { display: inline-block !important; vertical-align: middle !important; margin-right: 0.5rem !important; width: 1rem !important; height: 1rem !important; stroke-width: 2 !important; } /* Unselected (circle) */ .custom-control .feather[data-icon="circle"] { stroke: #868e96 !important; fill: none !important; } /* Selected (disc) */ .custom-control .feather[data-icon="disc"] { stroke: #4fc3f7 !important; fill: #4fc3f7 !important; } ```
Author
Owner

@Feriman22 commented on GitHub (Aug 23, 2025):

Working and easy solution here:
https://github.com/NginxProxyManager/nginx-proxy-manager/issues/4314#issuecomment-2888707741

<!-- gh-comment-id:3217401150 --> @Feriman22 commented on GitHub (Aug 23, 2025): Working and easy solution here: [https://github.com/NginxProxyManager/nginx-proxy-manager/issues/4314#issuecomment-2888707741](https://github.com/NginxProxyManager/nginx-proxy-manager/issues/4314#issuecomment-2888707741)
Author
Owner

@Linouxs commented on GitHub (Sep 12, 2025):

Working and easy solution here: #4314 (comment)

I use this method too but I add the theme with Nginx proxy manager itself: https://docs.theme-park.dev/setup/#nginx-proxy-manager

With this method you don't have to download the files and config Docker. This is my config:

Image
<!-- gh-comment-id:3284567184 --> @Linouxs commented on GitHub (Sep 12, 2025): > Working and easy solution here: [#4314 (comment)](https://github.com/NginxProxyManager/nginx-proxy-manager/issues/4314#issuecomment-2888707741) I use this method too but I add the theme with Nginx proxy manager itself: https://docs.theme-park.dev/setup/#nginx-proxy-manager With this method you don't have to download the files and config Docker. This is my config: <img width="523" height="779" alt="Image" src="https://github.com/user-attachments/assets/d8ccade3-6577-49dc-8bd8-0704f5874046" />
Author
Owner

@7heMech commented on GitHub (Nov 11, 2025):

This can be closed since new version has dark mode. @jc21

<!-- gh-comment-id:3516846515 --> @7heMech commented on GitHub (Nov 11, 2025): This can be closed since new version has dark mode. @jc21
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/nginx-proxy-manager-NginxProxyManager#2351
No description provided.