Upgrade from Bard v1 to v2

A guide for upgrading from Bard v1 to v2.


A new version of Bard (and Tiptap, the library that Bard is built on) was introduced in Statamic 3.4.

There is nothing you need to do to upgrade Bard or Tiptap since they're included in the Statamic upgrade, however if you have any custom extensions, you'll need to make some adjustments.

JavaScript Extensions

Extensions no longer need to use our wrappers. You can now use regular Tiptap extensions.

Here's how you'd import and bootstrap the extension into Statamic.

import AwesomeExtension from './AwesomeExtension';
import { AwesomeExtension } from './AwesomeExtension';
Statamic.$bard.addExtension(({ mark }) => mark(new AwesomeExtension));
Statamic.$bard.addExtension(() => AwesomeExtension);

Here's just the "container" of your extension (so you don't get overwhelmed by a large diff).

const { Mark } = Statamic.$bard.tiptap.core;
export default class AwesomeExtension {
export const AwesomeExtension = Mark.create({
// ...

And here are the various inner parts of the extension. Starting with name now being a property, and should be camelCased:

name() {
return 'awesome_extension'
name: 'awesomeExtension'

Schema is split into parseHTML and renderHTML:

schema() {
return {
parseDOM: [
{ style: 'color: red; font-family: cursive' }
toDOM: () => ['span', { style: 'color: red; font-family: cursive' }, 0],
parseHTML() {
return [
{ style: 'color: red; font-family: cursive' }
renderHTML() {
return ['span', {style: 'color: red; font-family: cursive'}, 0];

All commands are explicitly added by name:

commands({ type, toggleMark }) {
return () => toggleMark(type)
addCommands() {
return {
toggleAwesome: () => ({ commands }) => {
return commands.toggleMark(this.type);


Buttons can largely remain the same. You need to use the new camelCase name, and use a function to call your command manually. In this example we'll use the toggleAwesome command defined above.

Statamic.$bard.buttons((buttons, button) => {
return button({
name: 'awesome_extension',
name: 'awesomeExtension',
text: __('Awesome'),
command: 'fancy',
command: (editor) => editor.chain().focus().toggleAwesome().run()

PHP Extensions

On the PHP side, we no longer use the prosemirror-to-html package. We now use the more official tiptap-php package. The classes have changed a little.

namespace App\Bard;
use ProseMirrorToHtml\Marks\Mark;
use Tiptap\Core\Mark;
use Tiptap\Utils\HTML;
class Awesome extends Mark
protected $markType = 'awesome_extension';
public static $name = 'awesomeExtension';
public function tag()
public function renderHTML($mark, $attributes = [])
return [
'tag' => 'span',
'attrs' => [
'style' => 'color: red; font-family: cursive'
'style' => 'color: red; font-family: cursive'
], $attributes),

To add or replace extensions, there is no longer a difference between marks and nodes. You now specify the name and pass the extension.

Augmentor::addExtension('awesome_extension', new Awesome);
Augmentor::replaceMark(DefaultBold::class, CustomBold::class);
Augmentor::replaceExtension('bold', new CustomBold);
Docs feedback

Submit improvements, related content, or suggestions through Github.

Betterify this page →