Change log¶
Next version¶
0.28 (2026-10-26)¶
Renamed the
Typographicextension toSpecialCharactersto avoid confusion with Tiptap’sTypographyextension, which does something different.Typographicstill works as a deprecated alias, both in Python and in JavaScript, but logs a warning to the browser console. The--prose-editor-special-charactersCSS property replaces--prose-editor-typographic, which is still used as a fallback.
0.28a9 (2026-10-20)¶
Switched from the deprecated
JS(src, {...})form of django-js-asset toScript(src, **attrs), also in the presets documentation.
0.28a8 (2026-10-19)¶
The sanitizer keeps the
<div class="tableWrapper">which theTableextension’srenderWrapperoption adds, and no other classes on<div>. The wrapper was stripped before, so the option had no effect on sanitized fields.
0.28a7 (2026-10-17)¶
Actually transpiled the JavaScript.
0.28a6 (2026-10-17)¶
Images chosen through the
Figureextension’s file picker (pickerUrl) store a reference to the file as adata-fileattribute, set from theidpassed by the file browser (django-cabinet 0.20.1 or newer). The attribute is allowed by the sanitizer and dropped when the image URL is changed by hand.Raised the minimum version of django-cabinet in the
cabinetextra to 0.20.1.
0.28a5 (2026-10-14)¶
Reverted resolving the
jsentries ofDJANGO_PROSE_EDITOR_EXTENSIONSthroughstatic(): It’s impossible to distinguish static paths from module specifiers mapped by an import map, and the latter crashed when using the manifest static files storage. The entries are passed toimport()as-is again; wrap static files instatic_lazy().
0.28a4 (2026-10-14)¶
Added French translations. Thanks @iliyasalve!
Updated dependencies.
0.28a3 (2026-10-02)¶
Updated dependencies.
The
jsentries ofDJANGO_PROSE_EDITOR_EXTENSIONSno longer have to be wrapped instatic_lazy(); plain static paths are resolved usingstatic()when rendering the editor, consistent with import maps.static_lazy()values and absolute URLs continue to work. (Reverted again after 0.28a4, static files have to be wrapped instatic_lazy().)
0.28a2 (2026-09-30)¶
Fixed the flaky integration tests in CI (hopefully).
Updated dependencies.
Backfilled the CHANGELOG to contain patch releases.
0.28a1 (2026-09-28)¶
Updated the media and import map handling for DEP 0022 and django-js-asset 5.0a1.
0.27.3 (2026-09-21)¶
Updated Tiptap.
Added testing using Django 6.1.
0.27.2 (2026-08-27)¶
Fixed the broken presentation of the editor in Django 6.1.
0.27.1 (2026-08-24)¶
Fixed a crash when parsing
<ol>elements without adata-typeattribute.
0.27 (2026-08-13)¶
Updated Tiptap and ProseMirror dependencies.
Changed the bundled
CodeBlockandCodeextension to automatically add menu items.
0.26 (2026-06-11)¶
Requires django-js-asset 4.0 or newer. The editor’s import map is now carried by the widget and field media and merged through
js_asset.Mediainstead of the globalimportmapobject that django-js-asset 4.0 has removed. Rendering{{ form.media }}now emits the<script type="importmap">automatically – in the admin and in your own frontend templates – so you can drop thejs_asset.context_processors.importmapcontext processor and the{{ importmap }}tag from your templates.Rewrote the
Figureextension to handle both figure-wrapped images and standalone bare images. The caption field has been removed from the edit dialog (it stripped all formatting from the caption text). Instead, a floating bubble menu appears whenever an image or figure is selected, offering an “Add caption” / “Remove caption” action. Removing the caption from a<figure>also removes the<figure>wrapper, reverting to a bare<img>. The oldinsertFigurecommand is kept as an alias for the neweditImagecommand.Added a
pickerUrloption to theFigureextension for integrating CKEditor 4-style filebrowsers. Any file management solution supporting this protocol can be used, for example django-cabinet.The file picker integration (
pickerUrl) now pre-populates the alt text and caption fields from the picker’s response data (alternative_textandcaptionattributes).Added a caption field to the “Insert Figure” dialog. If filled in, a
<figcaption>is created alongside the image; if left blank, the figure is inserted without a caption.Removed the
urlformat constraint from the image URL field so that relative paths are accepted in addition to absolute URLs.
0.25.1 (2026-03-26)¶
Updated dependencies.
Set up trusted publishing for releases.
0.25 (2026-03-17)¶
Add a menu button to enable table deletion.
0.24.1 (2026-02-27)¶
Updated Tiptap and other dependencies.
Exported the Tiptap
InvisibleCharactersextension.Removed the custom
titleattribute handling from theLinkextension since the latest version of Tiptap’s link extension now includes it by default.Expanded the documentation to make the importmap requirement more prominent. Added concrete examples to both the installation and forms documentation to help prevent configuration issues when using the editor outside the Django admin.
0.24 (2026-01-30)¶
Made it possible to configure the available ordered list types, changed the code to emit inline styles. Added a bullet-type ordered list type because this makes nested lists of mixed types easier to create.
0.23.2 (2026-01-29)¶
Updated Tiptap and ProseMirror.
0.23.1 (2026-01-15)¶
Updated the dependencies.
0.23 (2026-01-13)¶
Changed the Django admin table styling overrides to be less opinionated and closer to the defaults. Thanks @mo-we!
0.22.5 (2025-12-29)¶
Updated Tiptap.
Added Django 6.0 and Python 3.14 to the CI list.
Fixed a bug where the unlink menu button was unavailable.
0.22.4 (2025-12-11)¶
Raised the misleading low limits for columns and rows when inserting a new table.
Started exposing the
prosemirror-tablesexports.Added polish translations. Thanks @kgunia!
0.22.3 (2025-12-02)¶
Fixed the prose editor textarea widget to not use the HTML5
requiredattribute. Thanks to @undefined-landmark for the report and the help testing the fix!
0.22.2 (2025-11-18)¶
Updated dependencies.
0.22.1 (2025-11-17)¶
Added
setNodeClassandunsetNodeClasscommands to theNodeClassextension. Each configured node or mark type now gets its own dropdown in the menu.
0.22 (2025-11-17)¶
Also apply the “actually empty” behavior in the frontend code. ProseMirror always produces at least one empty block-level element (for example
<p></p>). We prefer the editor to produce an empty string in this case instead. This may be a visible behavior change if you’re only using the frontend code and not the backend code; the backend code already applied the same transformation since django-prose-editor 0.4.
0.21.1 (2025-11-13)¶
Updated Tiptap and ProseMirror.
0.21 (2025-11-12)¶
Modified our
OrderedListextension to also set adata-typeattribute on the<ol>element with one of the CSS values for thelist-style-typeproperty. This is necessary because Chromium-based browsers cannot case sensitively match thetypeattribute.
0.20.1 (2025-11-10)¶
Updated Tiptap.
0.20 (2025-11-04)¶
Extended the
NodeClassextension to support marks (bold, italic, links, etc.) in addition to nodes. CSS classes can now be applied to marks by including them in thecssClassesconfiguration alongside nodes.Refactored the
NodeClassandLinkextensions to use Tiptap’supdateAttributes()command instead of the unsetMark/setMark pattern, which automatically preserves other mark attributes.
0.19 (2025-10-29)¶
Added an easier way to define the menu structure without having to go to the low level menu creator function and copy pasting the default menu groups.
0.18.5 (2025-10-21)¶
Updated Tiptap and ProseMirror.
Mentioned the licenses of bundled software in the
LICENSEfile.
0.18.4 (2025-09-19)¶
Added a description to the HTML extension’s textarea which explains that the HTML is restricted by the editor schema.
0.18.3 (2025-09-15)¶
Refactored the node class extension to use a single function to walk the ancestor list.
Changed the CSS overrides so that paragraphs in table header cells inherit the font weight.
0.18.2 (2025-09-10)¶
Fixed the table style overrides to work better in dark mode.
0.18.1 (2025-09-03)¶
Updated the documentation to provide working examples by including the necessary dependencies. Thanks @benopotamus and @j4lib!
Updated the sanitization documentation to correctly say which HTML tags and attributes are actually allowlisted by which extensions.
Updated the Tiptap dependency and pre-commit hooks.
0.18 (2025-08-27)¶
Backwards incompatible: Removed the automatic dependency management of some extensions. For example, adding
BulletListwould automatically add theListItemextension. This didn’t work nicely when replacing theListItemextension with a hypotheticalExtendedListItemextension because then the configuration would contain several list item nodes. The config resolver tries detecting invalid configurations and warns if it suspects missing extensions, but that’s not completely watertight. The warnings will be removed after a few releases.Added a
NodeClassextension for applying CSS classes to nodes.
0.17 (2025-08-25)¶
Updated Tiptap to 3.0.7. Also updated all ProseMirror packages and added explicit ProseMirror dependencies to package.json.
Rewritten menu system: The Menu extension now uses an
itemscreator function instead of the deprecatedaddItemsfunction. This provides more flexibility for custom menu layouts. AddedcreateMenuFromGroupshelper for converting simple group configurations. Extensions now receive{ editor, buttons, menu }parameters inaddMenuItemsmethod.Added menu configuration documentation as a new chapter.
Updated custom extensions documentation to use the new menu API with
menu.defineItem()instead of the deprecatedaddItemsapproach.Added
TextClassextension for applying CSS classes to text sections. This provides a clean, semantic alternative to inline styles, allowing arbitrary CSS classes on<span>tags with automatic menu integration and sanitization support.Separated dialog styles into their own CSS file (
dialog.css).Separated menu styles into their own CSS file (
menu.css).Updated pre-commit hooks and biome configuration.
Fixed import ordering and added missing imports in Python files to address linting issues.
Removed custom HorizontalRule extension in favor of Tiptap’s default implementation, which now includes proper insertion validation.
Exported Tiptap’s
Placeholderextension. Note that you need to add the CSS to actually display the placeholder yourself, see the Placeholder docs.Modified the
HTMLextension to preserve whitespace insidepreelements during prettification. Also, changed the extension to only run prettification on demand.Added a maximum width to prose editor dialog elements.
0.16.1 (2025-07-18)¶
Updated Tiptap to 3.0.1. Also updated all ProseMirror packages.
Changed the
.prose-editor-fullscreenclass to.prose-editor.fullscreento match.prose-editor.disabled.Bumped the
[sanitized]extra’s nh3 dependency to 0.3 and started taking advantage of the reusableCleanerobject. This allows us to initialize the cleaner once only.
0.16 (2025-07-11)¶
Updated Tiptap to 3.0.0-beta.29.
Change the widget implementation and add more easily reusable
forms.Mediaobjects and helpers.
0.15.2 (2025-07-08)¶
Updated Tiptap to 3.0.0-beta.25, we now also ship the
enableDevToolsoption.Changed the contents of
staticto all be bundled instead of having a mixture of hand-edited and generated assets.
0.15.1 (2025-07-07)¶
Provide the expected context to
addMenuItemsso that accessingthisactually does the right thing.
0.15 (2025-07-04)¶
Extensions can now register menu items using the
addMenuItemsmethod, which provides a cleaner API for menu integration.
0.14.1 (2025-07-02)¶
Dropped the JavaScript-based sticky menubar behavior, the menubar uses
position: sticky. Also dropped thestickyoption from theMenuagain. Override the behavior with CSS instead.
0.14 (2025-07-02)¶
Made the
Menuextension more reusable, introduced thedefaultItems,stickyandcssClassoptions. Started passing abuttonshelper into menu item creation functions which automatically uses the correctcssClassprefix when creating menu button DOM elements.
0.13.1 (2025-06-30)¶
Updated the pre-commit hooks.
Updated the Tiptap dependency.
Actually started dispatching the documented
prose-editor:readyevent when using the default preset.
0.13 (2025-06-25)¶
Switched from esbuild to rslib. Bundles are smaller and I’m a heavy user of rspack anyway.
Updated Tiptap to 3.0.0-beta.16, which allows us to remove our custom code to check whether we can insert figures or horizontal rules at the current selection.
Fixed the alignment of small contents in prose menubar buttons.
0.12 (2025-05-12)¶
Changed the prose editor dialog to use
div.prose-editor-dialog-fieldelements to wrap inputs and their labels instead of paragraphs.Allowed callable default values in the
updateAttrsDialog.
0.11.4 (2025-05-06)¶
Actually included the source maps in the package.
0.11.3 (2025-05-05)¶
Updated the Tiptap version to the 3.0 beta to avoid problems with extensions sharing storage over multiple editor instances.
Started including source maps again.
Convert textareas to use autogrow.
0.11.2 (2025-04-28)¶
Changed the ordered list menu button to disable itself when an ordered list cannot be inserted.
Updated the figure menu button to actually check whether figures can be inserted or not. Same for the horizontal rule menu button.
Added styles to selected nodes so that e.g. selected horizontal rules are shown as such.
0.11.1 (2025-04-27)¶
Updated the Tiptap version to the released 3.0 beta.
Fixed the menu to not run commands on click when the command is disabled.
Changed the
addLinkcommand to not do anything if the selection is empty or if the selection isn’t inside a link mark currently.Fixed the title attribute functionality of link marks. Titles have been inadvertently broken since 0.10 because I missed the fact that the Tiptap link extension doesn’t define the attribute in the schema.
0.11 (2025-04-16)¶
Added a new way of configuring the
ProseEditorFieldby using theextensionsargument. This allows specifying Tiptap extensions to use and also optionally allows configuring them. nh3 sanitization rules are automatically derived from the extension configuration when using sanitization. A system check warning is emitted if you’re using this mechanism but haven’t opted into sanitization.Using the
ProseEditorFieldwithout theextensionsparameter has been deprecated, and a system check warning has been added for automatically detecting this.Added support for specifying editor extensions using the
DJANGO_PROSE_EDITOR_EXTENSIONSsetting, which allows transparently adding JavaScript modules to the editor without having to write your own preset. Writing presets is and will be supported for even more advanced use cases, but the extensions mechanism hopefully covers 99% of all use cases.Switched the JavaScript to use ES modules and importmaps. If you’ve been using 0.10 you have to update your code to use ES modules (
<script type="module">) instead of deferred scripts. Sorry for the churn. Also check the import locations, ProseMirror functions have been moved into thepm.*namespace.Updated Tiptap to the 3.0.0 pre-release. This was the easiest way to ensure that extensions all get their unique storage per editor instance instead of (unexpectedly!) shared storage without resorting to hacks.
Added Django 5.2.
Modified the
HTMLextension to prettify the HTML code somewhat.Added a new
Fullscreenextension.Changed the
updateAttrsDialogto insert the dialog element into the parent element of theEditorViewDOM element instead of searching for an element with aprose-editorclass. This makes the function more reusable for even more exotic customizations of the editor.Added a “open in new window” checkbox to the link dialog. This can optionally be disabled by configuring the extension when using a custom preset using
Link.configure({ enableTarget: false }). Also removednofollowandnoreferrerfrom therelattribute of links since they do not make sense in a CMS context. Thanks to @yoshson for getting this started!Added integration testing using playwright.
Pruned the CI matrix a bit, stopped running tests using Python 3.11 and Django 5.0. Python 3.10 and Django 4.2 are still tested so we should be safe.
Added list style overrides to hopefully make lists usable with the Grappelli admin skin.
Disallowed overriding the
defaultand theconfigurableeditor preset.Hide the menubar when the editor is disabled.
Removed min and max width from the
.prose-editorDIV.Added an optional
sanitizeargument to theProseEditorFormFieldwhich allows form-level sanitization of HTML.The
sanitizeargument can also be a list of functions receiving and returning HTML. The list is processed in reverse (the first function is called last). If thecreate_sanitizerfunction is included, it’s automatically used to build a sanitizer for the configured editor extensions.
0.10.4 (2025-02-26)¶
Updated Tiptap.
0.10.3 (2025-01-21)¶
Fixed the django-content-editor support tweak where an empty label would make the editor move to the left border.
Updated Tiptap.
Added Django 5.2a1.
0.10.2 (2024-12-20)¶
Fixed a bug where the link mark wasn’t applied correctly. The buggy 0.10.0 package has been yanked.
Applied the
--prose-editor-backgroundand--prose-editor-foregroundCSS variables to the ProseMirror editing area.
0.10.1 (2024-12-17)¶
Fixed the link mark not being set when adding links.
0.10 (2024-12-17)¶
Changed the editor foundation to use Tiptap and bundled many of the available extensions. Tiptap uses ProseMirror under the hood, but offers an extension framework which I’d have to reinvent and there’s really no point to do that. The change should be backwards compatible if you only used the Python-level integration. The JavaScript integration has changed a lot,
DjangoProseEditor.createEditordoesn’t exist anymore.Introduced support for presets. See the “Customization” heading in the README.
Introduced hidden menu buttons; it’s now possible to show and hide buttons depending upon the editor selection.
Fixed a misbehavior where the
ProseEditorFormFieldwould override a manually definedProseEditorWidget.Added a dependency on django-js-asset for our JavaScript and JSON shipping needs.
Changed the way editor dialogs are built from unsafe
innerHTMLmanipulation to proper DOM manipulation.Updated the pre-commit hooks.
Updated the bundled material icons font.
Made the ESBuild watch mode report build successes again.
0.9 (2024-10-30)¶
Added Python 3.13 to the CI matrix.
Disable interactions and the menubar on the editor when the textarea is
disabled.
0.8.1 (2024-09-11)¶
Updated the ProseMirror dependencies.
0.8 (2024-08-26)¶
Updated the ProseMirror dependencies.
Added extremely hacky german translations for the dialogs.
Added Django 5.1 to the CI matrix.
Allowed specifying the heading levels for the menu. The schema itself supports all heading levels (1-6) as before.
0.7.1 (2024-08-02)¶
Made the link button only active when the cursor is inside a link.
Added docs on read the docs.
0.7 (2024-08-02)¶
Documented the CSS custom properties. Thanks @carltongibson!
Converted the block type dropdown back to a button group.
Changed the CSS so that block type buttons look active instead of disabled when in a block of the respective type.
Stopped showing the ‘remove link’ button as active when inside a link – it’s not active, just enabled.
Improved the styles of the dialog a bit.
0.6.3 (2024-08-01)¶
Added more unittesting.
Supported using the
ProseEditorFormFieldwith widget instances, not just with widget classes.
0.6.2 (2024-07-30)¶
Properly restored the textarea element when destroying the editor.
0.6.1 (2024-07-30)¶
Added the
django-prose-editor[sanitize]extra which automatically installs thenh3dependency. Thanks @plenaerts!
0.6 (2024-07-26)¶
Updated all dependencies.
Moved the Django administration interface CSS overrides into their own file, and only load them if necessary so that using the editor outside the admin requires using less
!importantoverrides.
0.5.1 (2024-07-11)¶
Added support for highlighting soft hyphens.
0.5 (2024-07-08)¶
Enabled showing typographic characters by default.
Changed the editor initialization to make the initial
textareaa child of the.prose-editordiv, and changed the CSS todisplay: none !important;so that thetextareais only shown in exceptional circumstances, when people really really want it.
0.4.7 (2024-07-08)¶
Fixed a typo in the
typographicconfiguration key which made it impossible to enable showing typographic characters.
0.4.6 (2024-07-07)¶
Fixed the typographic characters plugin adding more and more decorations on each edit.
0.4.5 (2024-07-06)¶
Improved the performance of the typographic characters plugin with large documents.
Improved the display of non-breaking spaces.
0.4.4 (2024-07-05)¶
Added optional support for showing typographic characters.
0.4.3 (2024-06-21)¶
Stopped putting anything into the global scope in
init.js.
0.4.2 (2024-06-10)¶
Stopped keeping marks when splitting list items.
Added a list of supported node and mark types to the README.
0.4.1 (2024-06-08)¶
Updated all dependencies.
0.4 (2024-05-26)¶
Dropped the dependency on
admin/js/jquery.init.js. We’re using our own DOM-ready handler and therefore can still accessdjango.jQueryto hook up the inline events handler if running inside the Django admin.Moved the paragraph formats into a popover.
0.3.4 (2024-04-26)¶
Stopped setting a black color on the
.ProseMirrorclass by default.
0.3.3 (2024-04-18)¶
Fixed the default configuration handling to actually work as documented.
0.3.2 (2024-04-18)¶
Tweaked the cleaning methods of
ProseEditorFieldandSanitizedProseEditorFieldto produce empty strings when no content is entered. Previously they would produce an empty paragraph (<p></p>) since our ProseMirror schema says that there exists always one or more block nodes.
0.3.1 (2024-04-11)¶
Allowed installing the package in Python 3.10 environments too.
0.3 (2024-04-09)¶
Switched the
SanitizedProseEditorFieldfrom html-sanitizer (which at the moment uses the problematic lxml HTML cleaner under the hood) with nh3. html-sanitizer is still a good choice but since we build on ProseMirror we only require a sanitizer, we don’t have to clean up strange HTML.Added customization options to the fields and widgets.
0.2.1 (2024-03-15)¶
Made the editor usable in dark mode.
Changed the cancel buttons in dialogs to not validate the form.
0.2 (2024-03-12)¶
Added client side validation to dialogs.
Upgraded esbuild.
0.1.5 (2024-03-12)¶
Added material icons for the format bar.
0.1.4 (2024-03-12)¶
Rebuilt the bundled static assets.
0.1.3 (2024-03-12)¶
Added
django_prose_editor.sanitized.SanitizedProseEditorFieldwhich automatically does the right thing.Added a button to the menu to insert horizontal rules.
0.1.2 (2024-03-12)¶
Extended the README.
Cleaned up the styles.
Added a maximum width to the editor.
Started hiding labels for prose editor fields in the Django admin if the label is an empty string. This looks better to me.
Added a shortcut for adding links.
Added a button for editing the raw HTML. This is sometimes useful.
Stopped generating source maps unless in dev mode. I like source maps a lot in general, but the files are really big in this case.
0.1.1 (2024-03-11)¶
Fixed the initialization in Django admin inlines.
Added a server-side sanitization callback to the
ProseEditorField.Automatically added a
get_*_excerptmodel method to models using theProseEditorFieldas a convenience.
0.1 (2024-03-11)¶
Initial public release.