BookStack Release v25.12

Merry Christmas and happy holidays! Today we release BookStack v25.12. With prior recent releases being focused on back-end changes, I focused on this next release being a Christmas present composed of a variety of improvements and additions that would more directly impact BookStack users, so I hope you find something merry in this new version of BookStack!

Upgrade Notices

  • Database Requirements - The minimum database version has changed from MySQL 5.7 to 8.0, and MariaDB 10.2 to 10.6. BookStack may still work on older versions, but we won’t specifically test nor provide support for them. Those older versions are out-of-support themselves so it’s best to update where possible.
  • Permissions/Access - Anyone with comment-create or comment-update permissions will be technically able to search/list users in the system. The role edit view has been updated to note this. This is to support mention functionality.
  • Default User Preferences - Comment mention notification preferences have been added and are enabled by default, so any users with the “Receive & manage notifications” role permission will be opted-in to comment mention notifications by default. This can be disabled by users in their user preferences.

Mention Users in Comments

Within BookStack comments you are now able to use @user style mentioning:

A comment being edited in BookStack, with a blue marker in editor showing “@Paul Chuckle” with a drop-down below this which has a search bar and a list of users

When you enter an @ symbol a user select popup will show allowing you to search-for, and select, a known user. After a user has been selected, their name and profile link will be used as a reference in the comment. This can be clicked in the editor which will allow you to change the user mentioned.

When saved, that user will then be notified that they were mentioned in a comment, via an email which will include a direct link (and the content) of the comment:

View of a BookStack email notification for a comment mention, with details including the page name, page path, the commenter and the comment text. There’s also a button to view the comment, and a link to manage notification preferences

Mentions can be added/altered when editing a comment, although users will only be mentioned if they have not already been mentioned when the comment was created/updated before, to prevent multiple notifications to the same user from the same comment.

Note: To be notified, a user would need to have the “Receive & manage notifications” system permission enabled on one of their roles, and have their “Notify when I’m mentioned in a comment” user notification preference enabled. Unlike other notification preferences, this new user notification preference is enabled by default.

Content URL History System

When the names of shelves, books, chapters & pages change in BookStack, the link for that item can change also. Within an instance, we track cross-references between updates and auto-update links on such change, but of course this does not work for links shared outside of Bookstack.

If a URL was not found for a current page, we’d use the revision system to track and locate pages using their old links. This system did not cover all content types though, and this also relied on revisions existing, which would mean potentially broken links in a variety of scenarios.

In v25.12 we’ve added a purpose-built tracking system for content links, so that changes are recorded for all item types, providing much more reliable redirect to current content when old links are used.

When updating, existing history from page revisions will be transferred to allow the data from the old URL resolution system to work for this new implementation.

List Count Controls

The “Sorting” category in Settings is now titled “Lists & Sorting”, since in this release we’ve added a few options which allow you to control the per-page amount of items shown for the shelves, books, and search result pages:

A BookStack settings view titled “Lists & Sorting”, focused on a “Per-Page Display Limits” option with number fields for Shelves, Books and Search Results

The option advises using even multiples of 3 (eg; 18, 24, 30, etc…) since this typically fits many layout scenarios where elements may be shown in rows of 3, 2 or 1 depending on screen size.

Thanks to @Xenoamor for providing a pull request for this feature.

Internal Reference Handling on Copy

Back in BookStack v21.12 we added the ability to copy entire books and chapters, which was very useful in being able to create “Template” sections of content. One pain-point of this was that any links within that content would remain as-is, meaning links between pages within a copied book, would now refer to pages within the original source book, not the new copied version.

In this release, links between items within the scope of a copy operating are now automatically updated to reference the new versions instead, meaning you don’t have to go through to find & update each link.

New WYSIWYG Editor Initial Developer API

This release introduces a developer JavaScript-based API for the new WYSIWYG editor. The surface area of the API is very small to begin with, just allowing a few core actions like adding toolbar buttons, and inserting content, but the focus of this stage is to ensure the fundamentals are correct before expanding out further based upon feedback.

As an example of the API in its current state, the following code could be used via the “Custom HTML Head Content” customization setting to add a ‘Greet’ button to the toolbar which, when clicked, will insert a Bold “Hello!”:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<script>
window.addEventListener('editor-wysiwyg::post-init', event => {
    const {usage, api} = event.detail;
    // Check that it's the page editor which is being loaded
    if (usage !== 'page-editor') {
        return;
    }
    
    // Create a custom button which inserts bold hello text on press
    const button = api.ui.createButton({
        label: 'Greet',
        action: () => {
            api.content.insertHtml(`<strong>Hello!</strong>`);
        }
    });
    
    // Add the button to the start of the first section within the main toolbar
    const toolbar = api.ui.getMainToolbar();
    if (toolbar) {
      toolbar.getSections()[0]?.addButton(button, 0);   
    }
});
</script>

Documentation can be found in the code-base here.

I welcome feedback and capability requests via this discussion thread.

New WYSIWYG Editor Updates

Keeping on the theme of the new WYSIWYG editor, this had a few fixes & improvements for this release:

  • Updated focus control for popup modal forms to focus on first form-field on show, and restore focus to the editor on hide.
  • Fixed undefined default search value in link item search selector popup.
  • Updated item search selector popup to pre-fill search input with selected text range.

System CLI Updates

The BookStack System CLI, used for a range of infrastructure maintenance tasks, has also received some updates in this version of BookStack:

  • The init & update commands will now use download-vendor logic instead of using composer to install required PHP packages.
  • The init command will now use our source.bookstackapp.com code mirror instead of GitHub.
  • Used PHP package versions have been updated.

Updated CSS Handling for Light & Dark Modes

While BookStack mainly handles dark/light mode changes in the code via a class on the top-level HTML element, it would also swap in/out different dark/light specific variables depending on the user’s preference. This is fine for standard BookStack use, but meant that customizations could not dynamically change between light and dark modes on the page without page reloads, or issues.

In this release, both are included by default, so that customizations can change the theme instantly. For example, this basic customization would allow you to temporarily toggle the theme via header bar click:

1
2
3
4
5
6
7
8
9
<script type="module">
const header = document.querySelector('header#header');
if (header) {
    header.addEventListener('dblclick', (event) => {
        event.preventDefault();
        document.documentElement.classList.toggle('dark-mode');
    });
}
</script>

Translations

As ever, I’d like to thank all the great technicians of translating text below who have contributed text changes to BookStack since the last release:

  • Bernardo Maia (bernardo.bmaia2) - Portuguese, Brazilian - 142 words
  • m0uch0 - Spanish - 113 words
  • Indrek Haav (IndrekHaav) - Estonian - 81 words
  • Tahsin Ahmed (tahsinahmed2012) - Bengali - 66 words
  • scureza - Italian - 61 words
  • Amr (amr3k) - Arabic - 50 words
  • Tim (thegatesdev) - Dutch - 48 words
  • bojan_che - Serbian (Cyrillic) - 13 words
  • setiawan setiawan (culture.setiawan) - Indonesian - 11 words
  • Korab Arifi (korabidev) - Albanian - 4 words
  • Donald Mac Kenzie (kiuman) - Norwegian Bokmal - 1 word

Word counts are those tracked by Crowdin, indicating original EN words translated.

Next Steps

Over the next few weeks I’ll be focused on meta-level maintenance elements of the project. Initially I’ll be working on the 2025 blog post to look back on the last year, as we did last year and many years before it. Then it’ll be on to fully moving the project over to Codeberg as planned here, and this is something I’ll talk a bit more about within that upcoming 2025 blog post.

For the next release, I’m not too sure what direction I’ll head right now, whether I’ll take on something large or work on a variety of smaller elements. I’ll have to see what path looks best, which I may get clarity on after reflecting upon the past year. One thing which will be progressed is the new WYSIWYG editor, and especially its new API which I hope to get feedback upon, so we can move that further to replacing the existing WYSIWYG editor as the default some time in 2026.

Full List of Changes

Released in v25.12

  • Added user mentions for comments. (#5944, #560)
  • Added slug history tracking system. (#5913, #5411)
  • Added initial developer API for the new WYSIWYG editor. (#5928, #5763)
  • Added internal reference handling on content copying. (#5917, #3239)
  • Added settings to control the number of books/shelves that will be displayed per page. Thanks to @Xenoamor. (#5606, #2343)
  • Updated translations with latest Crowdin changes. (#5933)
  • Updated new WYSIWYG editor with a range of fixes. (#5939)
  • Updated BookStack system CLI to v0.4. (#5956)
  • Updated CSS dark/light mode handling so all css variables exist by default. (#5923)
  • Updated “Microsoft URL Rewrite Module for IIS” download link. Thanks to @gerundt. (#5952)
  • Updated image thumbnail generation to more reliably log issues on error. (#5869)
  • Updated database to add index to views table to make view-based queries more efficient. (#5948)
  • Updated application database requirements. (#5882)
  • Fixed search pagination not using APP_URL value, and breaking for sub-path usage. (#5951)
  • Fixed search pagination overflowing view on smaller screen sizes. (#5920)

Released in v25.11.6 - Security Release

  • Updated application PHP dependencies.

Released in v25.11.5

  • Updated OIDC state handling to prevent other requests causing the process to fail, which was occurring in Chromium based browsers. (#5929)
  • Updated session history handling to prevent redirects to common asset locations. (#5925)
  • Updated PHP dependency versions.

Released in v25.11.4

  • Fixed error thrown when attempting to send new comment notifications. (#5918)
  • Updated PHP dependency versions.

Released in v25.11.3

  • Fixed overly-strict image access permission changes in v25.11.2 which could block images when a secure storage option was used alongside public access. (#5906, #5909)
  • Updated app PHP dependencies to latest versions.

Released in v25.11.2

  • Fixed image permission checking in ZIP exports to prevent error and to align with UI access. (#5899, #5885)
  • Updated translations with latest Crowdin changes. (#5887)
  • Updated test environment refresh database command to set env timezone option to ensure test database is consistent. (#5881)
  • Updated app PHP dependencies to latest versions.

Released in v25.11.1

  • Fixes database queries causing errors with versions of MySQL <= 5.7. (#5877)

Header Image Credits: Photo by Giles Laurent (CC-BY-SA-4) - Image Modified