Skip to content

Conversation

@danduma
Copy link

@danduma danduma commented Dec 27, 2025

  • Added the ability to upload themes via a file input, including validation for required files.
  • Implemented theme deletion with confirmation dialog, ensuring the default theme cannot be deleted.
  • Enhanced theme management by dynamically importing theme components and styles, falling back to the default theme if necessary.
  • Updated GraphQL schema and resolvers to support theme queries and mutations.

…unctionality

- Added the ability to upload themes via a file input, including validation for required files.
- Implemented theme deletion with confirmation dialog, ensuring the default theme cannot be deleted.
- Enhanced theme management by dynamically importing theme components and styles, falling back to the default theme if necessary.
- Updated GraphQL schema and resolvers to support theme queries and mutations.
@auto-assign auto-assign bot requested a review from NGPixel December 27, 2025 12:25
@drumadrian
Copy link

hi @danduma

would you mind if i tested this on my laptop? 🤓

i use wiki.js for my startup and your theme feature looks cool 😎

i can upload screenshots of a theme being applied.

Have a good day,

Adrian
[email protected]
[email protected]
[email protected]

@NGPixel NGPixel added the under review Acknowledged, awaiting further review label Dec 27, 2025
@danduma
Copy link
Author

danduma commented Dec 27, 2025

Of course @drumadrian ! Let us know how it works :)

@drumadrian
Copy link

Of course @drumadrian ! Let us know how it works :)

Hi @danduma I hope I setup your branch correctly.

Here is the output with help organizing the information from ChatGPT:

I pulled this branch locally and was able to get Wiki.js to start successfully (DB connects, GraphQL loads, server listens on port 3000).

However, on first request the server errors with:

ENOENT: no such file or directory, open 'server/views/master.pug'

I double-checked:

  • server/views/master.pug does not exist on this branch
  • It also does not exist on requarks/wiki main
  • git diff origin/main..HEAD -- server/views shows no changes

The error originates from server/views/error.pug extending or referencing master.pug, which suggests the runtime is still expecting a base layout that no longer exists (or was renamed in a previous refactor).

This causes the app to crash on error rendering even though the server boots cleanly.

Happy to help track where the expected layout should now come from (or whether error.pug should extend a different base). Let me know how you’d like to proceed.

error

Here is the full console output:

drumadrian@braincloud wiki % 
drumadrian@braincloud wiki % mkdir -p assets
cp client/static/favicon.ico assets/favicon.ico 2>/dev/null || true
yarn start

yarn run v1.22.22
$ node server
Loading configuration from /Users/drumadrian/Documents/myhomeforcode2/wiki/config.yml... OK
2026-01-01T00:33:51.237Z [MASTER] info: =======================================
2026-01-01T00:33:51.237Z [MASTER] info: = Wiki.js 2.0.0 =======================
2026-01-01T00:33:51.237Z [MASTER] info: =======================================
2026-01-01T00:33:51.237Z [MASTER] info: Initializing...
2026-01-01T00:33:51.392Z [MASTER] info: Using database driver pg for postgres [ OK ]
2026-01-01T00:33:51.395Z [MASTER] info: Connecting to database...
2026-01-01T00:33:51.408Z [MASTER] info: Database Connection Successful [ OK ]
2026-01-01T00:33:51.619Z [MASTER] warn: Mail is not setup! Please set the configuration in the administration area!
2026-01-01T00:33:51.651Z [MASTER] info: Loading GraphQL Schema...
2026-01-01T00:33:52.352Z [MASTER] info: GraphQL Schema: [ OK ]
2026-01-01T00:33:52.423Z [MASTER] info: HTTP Server on port: [ 3000 ]
2026-01-01T00:33:52.433Z [MASTER] info: HTTP Server: [ RUNNING ]
2026-01-01T00:33:52.490Z [MASTER] info: No new analytics providers found: [ SKIPPED ]
2026-01-01T00:33:52.498Z [MASTER] info: Loaded 21 authentication strategies: [ OK ]
2026-01-01T00:33:52.502Z [MASTER] info: No new comment providers found: [ SKIPPED ]
2026-01-01T00:33:52.511Z [MASTER] info: No new editors found: [ SKIPPED ]
2026-01-01T00:33:52.522Z [MASTER] info: No new loggers found: [ SKIPPED ]
2026-01-01T00:33:52.542Z [MASTER] info: No new renderers found: [ SKIPPED ]
2026-01-01T00:33:52.551Z [MASTER] info: No new search engines found: [ SKIPPED ]
2026-01-01T00:33:52.562Z [MASTER] info: No new storage targets found: [ SKIPPED ]
2026-01-01T00:33:52.562Z [MASTER] info: Checking for installed optional extensions...
2026-01-01T00:33:52.572Z [MASTER] info: Optional extension git is installed. [ OK ]
2026-01-01T00:33:52.579Z [MASTER] info: Optional extension pandoc was not found on this system. [ SKIPPED ]
2026-01-01T00:33:52.586Z [MASTER] info: Optional extension puppeteer was not found on this system. [ SKIPPED ]
2026-01-01T00:33:52.586Z [MASTER] info: Optional extension sharp was not found on this system. [ SKIPPED ]
2026-01-01T00:33:52.592Z [MASTER] info: Authentication Strategy Local: [ OK ]
2026-01-01T00:33:52.844Z [MASTER] info: (COMMENTS/DEFAULT) Initializing...
2026-01-01T00:33:52.844Z [MASTER] info: (COMMENTS/DEFAULT) Initialization completed.
2026-01-01T00:33:52.848Z [MASTER] info: Purging orphaned upload files...
2026-01-01T00:33:52.849Z [MASTER] info: Syncing locales with Graph endpoint...
2026-01-01T00:33:52.850Z [MASTER] info: Fetching latest updates from Graph endpoint...
2026-01-01T00:33:52.881Z [MASTER] info: Purging orphaned upload files: [ COMPLETED ]
Loading configuration from /Users/drumadrian/Documents/myhomeforcode2/wiki/config.yml... OK
2026-01-01T00:33:52.936Z [JOB] info: Rebuilding page tree...
2026-01-01T00:33:53.091Z [JOB] info: Using database driver pg for postgres [ OK ]
2026-01-01T00:33:53.122Z [JOB] info: Rebuilding page tree: [ COMPLETED ]
2026-01-01T00:33:53.137Z [MASTER] info: Fetching latest updates from Graph endpoint: [ COMPLETED ]
2026-01-01T00:33:53.229Z [MASTER] info: Pulled latest locale updates for English from Graph endpoint: [ COMPLETED ]
2026-01-01T00:33:53.231Z [MASTER] info: Syncing locales with Graph endpoint: [ COMPLETED ]
Error: ENOENT: no such file or directory, open '/Users/drumadrian/Documents/myhomeforcode2/wiki/server/views/master.pug'
    at /Users/drumadrian/Documents/myhomeforcode2/wiki/server/views/error.pug line 1
    at Object.openSync (node:fs:574:18)
    at Object.readFileSync (node:fs:453:35)
    at Function.read (/Users/drumadrian/Documents/myhomeforcode2/wiki/node_modules/pug-load/index.js:85:13)
    at Object.read (/Users/drumadrian/Documents/myhomeforcode2/wiki/node_modules/pug/lib/index.js:164:25)
    at /Users/drumadrian/Documents/myhomeforcode2/wiki/node_modules/pug-load/index.js:28:25
    at walkAST (/Users/drumadrian/Documents/myhomeforcode2/wiki/node_modules/pug-walk/index.js:26:18)
    at /Users/drumadrian/Documents/myhomeforcode2/wiki/node_modules/pug-walk/index.js:112:20
    at Array.reduce (<anonymous>)
    at walkAndMergeNodes (/Users/drumadrian/Documents/myhomeforcode2/wiki/node_modules/pug-walk/index.js:111:18)
    at walkAST (/Users/drumadrian/Documents/myhomeforcode2/wiki/node_modules/pug-walk/index.js:40:19)
    at load (/Users/drumadrian/Documents/myhomeforcode2/wiki/node_modules/pug-load/index.js:13:10)
    at Function.loadString [as string] (/Users/drumadrian/Documents/myhomeforcode2/wiki/node_modules/pug-load/index.js:55:10)
    at compileBody (/Users/drumadrian/Documents/myhomeforcode2/wiki/node_modules/pug/lib/index.js:82:18)
    at exports.compile (/Users/drumadrian/Documents/myhomeforcode2/wiki/node_modules/pug/lib/index.js:269:16)
    at handleTemplateCache (/Users/drumadrian/Documents/myhomeforcode2/wiki/node_modules/pug/lib/index.js:242:25)
    at exports.renderFile (/Users/drumadrian/Documents/myhomeforcode2/wiki/node_modules/pug/lib/index.js:454:10)
    at exports.renderFile (/Users/drumadrian/Documents/myhomeforcode2/wiki/node_modules/pug/lib/index.js:444:21)
    at exports.__express [as engine] (/Users/drumadrian/Documents/myhomeforcode2/wiki/node_modules/pug/lib/index.js:493:11)
    at View.render (/Users/drumadrian/Documents/myhomeforcode2/wiki/node_modules/express/lib/view.js:135:8)
    at tryRender (/Users/drumadrian/Documents/myhomeforcode2/wiki/node_modules/express/lib/application.js:657:10)
    at Function.render (/Users/drumadrian/Documents/myhomeforcode2/wiki/node_modules/express/lib/application.js:609:3)
    at ServerResponse.render (/Users/drumadrian/Documents/myhomeforcode2/wiki/node_modules/express/lib/response.js:1039:7)
    at /Users/drumadrian/Documents/myhomeforcode2/wiki/server/master.js:194:11
    at Layer.handle_error (/Users/drumadrian/Documents/myhomeforcode2/wiki/node_modules/express/lib/router/layer.js:71:5)
    at trim_prefix (/Users/drumadrian/Documents/myhomeforcode2/wiki/node_modules/express/lib/router/index.js:326:13)
    at /Users/drumadrian/Documents/myhomeforcode2/wiki/node_modules/express/lib/router/index.js:286:9
    at Function.process_params (/Users/drumadrian/Documents/myhomeforcode2/wiki/node_modules/express/lib/router/index.js:346:12)
    at next (/Users/drumadrian/Documents/myhomeforcode2/wiki/node_modules/express/lib/router/index.js:280:10)
    at Layer.handle_error (/Users/drumadrian/Documents/myhomeforcode2/wiki/node_modules/express/lib/router/layer.js:67:12)
    at trim_prefix (/Users/drumadrian/Documents/myhomeforcode2/wiki/node_modules/express/lib/router/index.js:326:13)
    at /Users/drumadrian/Documents/myhomeforcode2/wiki/node_modules/express/lib/router/index.js:286:9
    at Function.process_params (/Users/drumadrian/Documents/myhomeforcode2/wiki/node_modules/express/lib/router/index.js:346:12)
    at Immediate.next (/Users/drumadrian/Documents/myhomeforcode2/wiki/node_modules/express/lib/router/index.js:280:10)
    at Immediate.<anonymous> (/Users/drumadrian/Documents/myhomeforcode2/wiki/node_modules/express/lib/router/index.js:646:15)
^C
drumadrian@braincloud wiki % 


screenshot:

Screenshot

@NGPixel
Copy link
Member

NGPixel commented Jan 1, 2026

@drumadrian You need to build the app first: yarn build

@drumadrian
Copy link

sorry 🤓 amateur mistake 😅

build success

build succeeded.....

dashboard

now I'll test a theme

@drumadrian
Copy link

Happy New Year 🥳

Here are the results of my initial theme testing.

Dark looks good but the Default theme may not be causing an issue based on my updates.

I will retry again with a fresh clone of the code and my theme zip file.

I included the zip file with my theme information and also the terminal output.

drumadrian@braincloud wiki % yarn start
yarn run v1.22.22
$ node server
Loading configuration from /Users/drumadrian/Documents/myhomeforcode2/wiki/config.yml... OK
2026-01-01T08:13:42.488Z [MASTER] info: =======================================
2026-01-01T08:13:42.489Z [MASTER] info: = Wiki.js 2.0.0 =======================
2026-01-01T08:13:42.489Z [MASTER] info: =======================================
2026-01-01T08:13:42.489Z [MASTER] info: Initializing...
2026-01-01T08:13:42.682Z [MASTER] info: Using database driver pg for postgres [ OK ]
2026-01-01T08:13:42.684Z [MASTER] info: Connecting to database...
2026-01-01T08:13:42.700Z [MASTER] info: Database Connection Successful [ OK ]
2026-01-01T08:13:42.934Z [MASTER] warn: Mail is not setup! Please set the configuration in the administration area!
2026-01-01T08:13:42.962Z [MASTER] info: Loading GraphQL Schema...
2026-01-01T08:13:43.202Z [MASTER] info: GraphQL Schema: [ OK ]
2026-01-01T08:13:43.272Z [MASTER] info: HTTP Server on port: [ 3000 ]
2026-01-01T08:13:43.279Z [MASTER] info: HTTP Server: [ RUNNING ]
2026-01-01T08:13:43.332Z [MASTER] info: No new analytics providers found: [ SKIPPED ]
2026-01-01T08:13:43.338Z [MASTER] info: Loaded 21 authentication strategies: [ OK ]
2026-01-01T08:13:43.344Z [MASTER] info: No new comment providers found: [ SKIPPED ]
2026-01-01T08:13:43.349Z [MASTER] info: No new editors found: [ SKIPPED ]
2026-01-01T08:13:43.356Z [MASTER] info: No new loggers found: [ SKIPPED ]
2026-01-01T08:13:43.372Z [MASTER] info: No new renderers found: [ SKIPPED ]
2026-01-01T08:13:43.378Z [MASTER] info: No new search engines found: [ SKIPPED ]
2026-01-01T08:13:43.386Z [MASTER] info: No new storage targets found: [ SKIPPED ]
2026-01-01T08:13:43.387Z [MASTER] info: Checking for installed optional extensions...
2026-01-01T08:13:43.396Z [MASTER] info: Optional extension git is installed. [ OK ]
2026-01-01T08:13:43.404Z [MASTER] info: Optional extension pandoc was not found on this system. [ SKIPPED ]
2026-01-01T08:13:43.411Z [MASTER] info: Optional extension puppeteer was not found on this system. [ SKIPPED ]
2026-01-01T08:13:43.412Z [MASTER] info: Optional extension sharp was not found on this system. [ SKIPPED ]
2026-01-01T08:13:43.414Z [MASTER] info: Authentication Strategy Local: [ OK ]
2026-01-01T08:13:43.643Z [MASTER] info: (COMMENTS/DEFAULT) Initializing...
2026-01-01T08:13:43.643Z [MASTER] info: (COMMENTS/DEFAULT) Initialization completed.
2026-01-01T08:13:43.656Z [MASTER] info: Purging orphaned upload files...
2026-01-01T08:13:43.656Z [MASTER] info: Syncing locales with Graph endpoint...
2026-01-01T08:13:43.657Z [MASTER] info: Fetching latest updates from Graph endpoint...
2026-01-01T08:13:43.697Z [MASTER] info: Purging orphaned upload files: [ COMPLETED ]
Loading configuration from /Users/drumadrian/Documents/myhomeforcode2/wiki/config.yml... OK
2026-01-01T08:13:43.746Z [JOB] info: Rebuilding page tree...
2026-01-01T08:13:43.930Z [JOB] info: Using database driver pg for postgres [ OK ]
2026-01-01T08:13:43.965Z [JOB] info: Rebuilding page tree: [ COMPLETED ]
2026-01-01T08:13:44.040Z [MASTER] info: Fetching latest updates from Graph endpoint: [ COMPLETED ]
2026-01-01T08:13:44.103Z [MASTER] info: Pulled latest locale updates for English from Graph endpoint: [ COMPLETED ]
2026-01-01T08:13:44.105Z [MASTER] info: Syncing locales with Graph endpoint: [ COMPLETED ]
2026-01-01T08:13:53.746Z [MASTER] info: Themes resolver called
2026-01-01T08:13:53.747Z [MASTER] info: Scanning themes directory: /Users/drumadrian/Documents/myhomeforcode2/wiki/client/themes
2026-01-01T08:13:53.747Z [MASTER] info: Found theme directories: default
2026-01-01T08:13:53.749Z [MASTER] info: Loaded theme: default - Default
2026-01-01T08:13:53.749Z [MASTER] info: Returning 1 themes
2026-01-01T08:14:33.625Z [MASTER] info: Themes resolver called
2026-01-01T08:14:33.625Z [MASTER] info: Scanning themes directory: /Users/drumadrian/Documents/myhomeforcode2/wiki/client/themes
2026-01-01T08:14:33.625Z [MASTER] info: Found theme directories: braincloud, default
2026-01-01T08:14:33.626Z [MASTER] info: Loaded theme: braincloud - Brain Cloud
2026-01-01T08:14:33.626Z [MASTER] info: Loaded theme: default - Default
2026-01-01T08:14:33.626Z [MASTER] info: Returning 2 themes
2026-01-01T08:14:51.266Z [MASTER] info: Themes resolver called
2026-01-01T08:14:51.267Z [MASTER] info: Scanning themes directory: /Users/drumadrian/Documents/myhomeforcode2/wiki/client/themes
2026-01-01T08:14:51.267Z [MASTER] info: Found theme directories: braincloud, default
2026-01-01T08:14:51.267Z [MASTER] info: Loaded theme: braincloud - Brain Cloud
2026-01-01T08:14:51.267Z [MASTER] info: Loaded theme: default - Default
2026-01-01T08:14:51.267Z [MASTER] info: Returning 2 themes
2026-01-01T08:15:04.255Z [MASTER] info: Themes resolver called
2026-01-01T08:15:04.255Z [MASTER] info: Scanning themes directory: /Users/drumadrian/Documents/myhomeforcode2/wiki/client/themes
2026-01-01T08:15:04.255Z [MASTER] info: Found theme directories: braincloud, default
2026-01-01T08:15:04.256Z [MASTER] info: Loaded theme: braincloud - Brain Cloud
2026-01-01T08:15:04.256Z [MASTER] info: Loaded theme: default - Default
2026-01-01T08:15:04.256Z [MASTER] info: Returning 2 themes
2026-01-01T08:15:23.390Z [MASTER] info: Themes resolver called
2026-01-01T08:15:23.390Z [MASTER] info: Scanning themes directory: /Users/drumadrian/Documents/myhomeforcode2/wiki/client/themes
2026-01-01T08:15:23.391Z [MASTER] info: Found theme directories: braincloud, default
2026-01-01T08:15:23.392Z [MASTER] info: Loaded theme: braincloud - Brain Cloud
2026-01-01T08:15:23.392Z [MASTER] info: Loaded theme: default - Default
2026-01-01T08:15:23.392Z [MASTER] info: Returning 2 themes
2026-01-01T08:15:33.903Z [MASTER] info: Themes resolver called
2026-01-01T08:15:33.903Z [MASTER] info: Scanning themes directory: /Users/drumadrian/Documents/myhomeforcode2/wiki/client/themes
2026-01-01T08:15:33.904Z [MASTER] info: Found theme directories: braincloud, default
2026-01-01T08:15:33.905Z [MASTER] info: Loaded theme: braincloud - Brain Cloud
2026-01-01T08:15:33.907Z [MASTER] info: Loaded theme: default - Default
2026-01-01T08:15:33.907Z [MASTER] info: Returning 2 themes
2026-01-01T08:15:36.459Z [MASTER] info: Themes resolver called
2026-01-01T08:15:36.459Z [MASTER] info: Scanning themes directory: /Users/drumadrian/Documents/myhomeforcode2/wiki/client/themes
2026-01-01T08:15:36.459Z [MASTER] info: Found theme directories: braincloud, default
2026-01-01T08:15:36.460Z [MASTER] info: Loaded theme: braincloud - Brain Cloud
2026-01-01T08:15:36.461Z [MASTER] info: Loaded theme: default - Default
2026-01-01T08:15:36.461Z [MASTER] info: Returning 2 themes
2026-01-01T08:15:43.306Z [MASTER] info: Themes resolver called
2026-01-01T08:15:43.307Z [MASTER] info: Scanning themes directory: /Users/drumadrian/Documents/myhomeforcode2/wiki/client/themes
2026-01-01T08:15:43.314Z [MASTER] info: Found theme directories: braincloud, default
2026-01-01T08:15:43.315Z [MASTER] info: Loaded theme: braincloud - Brain Cloud
2026-01-01T08:15:43.315Z [MASTER] info: Loaded theme: default - Default
2026-01-01T08:15:43.315Z [MASTER] info: Returning 2 themes


dark light home light admin page

braincloud.zip

@drumadrian
Copy link

Hi @danduma 👋 and @NGPixel 👋

Thanks for the work on this PR — I spent some time testing it locally and wanted to share what I’m seeing, along with a question on next steps.

What I’m observing

In client/client-app.js, if the SCSS import fails, the code falls back to:

siteConfig.theme = 'default'

inside the catch, but there’s no logging by default. From my testing, this makes it a bit tricky to tell why a custom theme didn’t load.

Based on the attached screenshots:

  • The Theme admin UI correctly shows the Brain 🧠 Cloud theme as uploaded and selectable.

  • The server logs show the theme being discovered and loaded (Loaded theme: braincloud – Brain Cloud).

  • However, in the browser console, siteConfig still resolves to:

    theme: "default"
  • As a result, the rendered page uses the default theme styles, even though the Brain 🧠 Cloud theme zip is present and valid.

This seems consistent with the SCSS import failing silently and triggering the fallback path.

Test details

  • I’m testing with a custom theme (Brain 🧠 Cloud) packaged per the theme spec.

  • The zip includes:

    • theme.yml
    • scss/app.scss
    • css/app.css (precompiled)
    • js/app.js
    • thumbnail.png
  • The theme zip is attached here for reference.

Question / next steps

To help isolate this further, what would you recommend trying next?

A few possibilities I was considering:

  • Temporarily adding logging in the SCSS import catch to confirm the exact failure reason
  • Confirming whether the client expects only compiled CSS, or still attempts to import SCSS at runtime in this path
  • Verifying whether the theme resolution logic should update siteConfig.theme earlier (before the SCSS import), so a style failure doesn’t implicitly reset the active theme
  • Checking whether a missing or mismatched build artifact (e.g. sourcemap / CSS filename) could trigger the fallback even when app.css exists

Happy to test additional changes or provide more logs if that helps. Thanks again — this PR is very close, and I’m excited to get custom themes fully unblocked 👍

siteConfig set to default theme set to Brain Cloud theme loaded

braincloud.zip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

under review Acknowledged, awaiting further review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants