Cause: You are most likely using a reverse proxy such as nginx or apache.
Resolution: Increase your reverse proxy configuration for file uploads.
Wiki.js is a Single-Page Application (SPA) which loads page contents lazily, on demand. While this is great for user experience, search engines may not render the page properly as a result.
To address this, unauthenticated requests (e.g. search engines, AI bots, etc.) receive a response with the page prerendered content.
This allows for content to be indexed correctly by search engines and bots, without the cost of server-side rendering.
Users with javascript disabled are also able to view the page contents, but without the application shell around it. This provides a fallback for such users.
tl;dr: Because it's not worth the significant downsides.
Long answer: It introduces many problems:
Path parsing: Assuming an installation at /wiki. If a user enters a link to /foobar, does it mean /foobar or /wiki/foobar? When creating a page, do you enter the subfolder in the path or not? What if the user does? Should it strips the subfolder? What if the user does want to put the page in a folder wiki under /wiki? When adding an image to a page, should it rewrite the path with the prefix? Having assets in a subfolder at the root is a very common case. One user would expect one behavior while another would expect the opposite. This becomes extremely confusing for both the developer and the end users.
Export/import: When exporting the page to a Git repository, should all the links be rewritten without the prefix? How about importing? Should it assume all links need to be prefixed? What if I want to link to another folder at the domain root?
Security: There's no isolation between the wiki and other services/apps running on the same host. Any script on the host can open pages in iframes and execute arbitrary code with the user session. Cookies can be read by any app on the domain.
Service workers: Any app on the same domain using service workers is now intercepting requests/responses meant for Wiki.js. In addition to the lack of security, you're also now dealing with potential stale assets because the service worker is in control of everything on the domain.
Storage collision: By hosting multiple sites on the same hostname, you're sharing the cookies and localStorage for that domain. If another site decides to change / delete the cookie used by Wiki.js, you'll run into issues. The cookie header is also limited in length (4096 characters) and can also lead to issues if too many apps set cookies (especially with JWT).
Passkeys/WebAuthn: Passkeys are registered on the domain, not per path. The same is true for password autofill in most cases.
Sitemap/Robots/Favicons: These special files can only live at the root, which means these features would be completely broken and non-functional.
Support: This is by far the biggest pain point. v1 had support for subfolder installations. The vast majority of support tickets were about reverse-proxy not setup correctly. Good docs alone cannot prevent this as there a million different reverse-proxy solutions and you'd be surprised how many users can't be bothered with reading docs in the first place. This puts a massive strain on developer support.
For these reasons, there's no plan to support subfolder installations for the foreseeable future.
Use a subdomain. If you absolutely can't, then sorry, use something else.
The only way to change a password, without access to the administration web UI, is via the database. Use a tool like pgAdmin if you're not comfortable with shell commands.
Warning
It's NOT possible to read the current password value. Passwords are stored using a one-way bcrypt hashing process, which is not reversible. You can only overwrite it with a new value.
The code below replaces the config for the Local Authentication strategy (which has a static ID of 5a528c4c-0a82-4ad2-96a5-2b23811e6588) for the [email protected] user (replace with your email address in the code below).
The new config sets a new temporary password of recovery123 and enables the "Must Change Password" flag to force a new password on the next login.
Tip
You can also generate a different password hash using a bcrypt hash generator set to
12rounds and set themustChangePwdflag tofalse. However, it's recommended to use the predefined hash below instead to avoid logging your actual password hash into the shell history.
Using pgAdmin or psql, execute the following query against your wiki database:
UPDATE wiki.users
SET auth = jsonb_set(
auth,
'{5a528c4c-0a82-4ad2-96a5-2b23811e6588}',
'{
"password": "$2a$12$VzIQGsgG4wjUNSNBPRwif.bDsMwsyy1R3Sox9yfVL1V3fYTya3sMq",
"tfaSecret": "",
"tfaIsActive": false,
"tfaRequired": false,
"mustChangePwd": true,
"restrictLogin": false
}'::jsonb,
true
)
WHERE email = '[email protected]';
Assuming your database container is named db with a wiki user and database name:
docker exec -i db psql -U wiki -d wiki <<'EOF'
UPDATE wiki.users
SET auth = jsonb_set(
auth,
'{5a528c4c-0a82-4ad2-96a5-2b23811e6588}',
'{
"password": "$2a$12$VzIQGsgG4wjUNSNBPRwif.bDsMwsyy1R3Sox9yfVL1V3fYTya3sMq",
"tfaSecret": "",
"tfaIsActive": false,
"tfaRequired": false,
"mustChangePwd": true,
"restrictLogin": false
}'::jsonb,
true
)
WHERE email = '[email protected]';
EOF
No but it's highly recommended as it includes all the necessary dependencies. Many IDEs now support devcontainers so you're no longer limited to VS Code.
Yes. Claude by Anthropic was used as a coding assistant. However, it was always used in a very directed manner for specific features. Every button, form element, API endpoint, DB schema fields, UX behavior, etc. is intentional and reasoned.
Nothing was "vibe-coded" or done using AI agents left on their own with instructions to follow a plan. This is a recipe for disaster and a great way to end up with insecure, buggy and unmaintainable software.
All documentation is written by a human.
Yes BUT a human must have reviewed the entirety of the proposed code and is fully responsible for it.