✨ Koenig Editor - Beta Release


Thanks @JxB! I’ve added it to the x-browser compatibility list in the RC issue


I find myself wanting a few things:

  • swap/move cards. I’ve recently migrated my blog and am wanting to restructure a few posts. Or move a picture up or down. At the moment this is real pain.
  • I’d love a code snippet card. Especially one where I can select the language for enhanced pretty printing.
  • I’d love a carousel mode, where I can join one or more embeds, images and have them in a rotating panel

And a few bugs:

  • When I first edit a post imported as Markdown I get a 500 error on save. The post is correctly converted and saved.
  • Some Markdown panels become really wide in read mode. Especially when the text contains long urls or code snippets. Renders fine in the real blog and in edit mode.
  • when doubleclicking a section in a post with multiple sections the browser sometimes jumps after the first click and then the second click is captured by an adjacent block. Thus turning the wrong block in edit mode. Similarly, when doubleclicking a large block, the cursor usually ends up near the bottom, thus having to scroll back up to find where you wanted to edit the text.


This is definitely planned but not currently planned for the very first release, there’s quite a lot of other things to cover first :slight_smile:

This already exists, you can use ``` right now as you would in Markdown. Language support for the code snippet card is also coming soon.

This would be a new card. No current plans to make this a built-in card but Koenig will eventually allow completely custom cards to be created and installed.

Do you still have the logs from that request? We can’t really debug without them as we don’t know what happened.

Thanks, we’ll have a look at the styling for that.

This should hopefully be fixed in the upcoming 1.24.2 release.

Do you mean when double-clicking a large Markdown/HTML card? It’s difficult to determine exactly where in the raw markdown/HTML content a double-click was intended for. Maybe we can look at not auto-focusing the content in certain circumstances though so it feels a bit less frustrating with jumping cursors.


New issue in Chrome with Koenig and Grammarly for Chrome enabled the CPU just spikes:

Hmmmm… This repros pretty well using:

  • Install and enabe Grammarly for Chrome
  • select a piece of text in a story
  • click the insert hyperlink button
  • navigate to another tab
  • use copy link address to grab the hyperlink off a link on the other tab
  • navigate back to the ghost tab, bingo 100%


The clientside stacktrace for the

This is the javascript error:

vendor.min-53d49a3c7e263c848106e1538838d3f3.js:3597 Uncaught TypeError: Cannot read property 'targetName' of undefined
    at o.error (vendor.min-53d49a3c7e263c848106e1538838d3f3.js:3597)
    at o._ (vendor.min-53d49a3c7e263c848106e1538838d3f3.js:3609)
    at f (vendor.min-53d49a3c7e263c848106e1538838d3f3.js:4173)
    at e.trigger (vendor.min-53d49a3c7e263c848106e1538838d3f3.js:4303)
    at o.send (vendor.min-53d49a3c7e263c848106e1538838d3f3.js:3555)
    at o.send (vendor.min-53d49a3c7e263c848106e1538838d3f3.js:3755)
    at o.<anonymous> (ghost.min-f890f42fd7ab049143bfb83e307e291e.js:528)
    at M (vendor.min-53d49a3c7e263c848106e1538838d3f3.js:1177)
    at Generator._invoke (vendor.min-53d49a3c7e263c848106e1538838d3f3.js:1175)
    at Generator.e.(/ghost/anonymous function) [as next] (https://scrumbug.ghost.io/ghost/assets/vendor.min-53d49a3c7e263c848106e1538838d3f3.js:1177:326)
error @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:3597
_ @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:3609
f @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:4173
e.trigger @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:4303
send @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:3555
send @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:3755
(anonymous) @ ghost.min-f890f42fd7ab049143bfb83e307e291e.js:528
M @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:1177
(anonymous) @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:1175
e.(anonymous function) @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:1177
_resumeGenerator @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:12641
_handleResolvedContinueValue @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:12651
_proceed @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:12644
e.invoke @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:2410
e.flush @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:2403
e.flush @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:2415
e.end @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:2427
e._run @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:2468
e._join @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:2467
e.join @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:2436
y.join @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:3071
(anonymous) @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:11999
l @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:1339
fireWith @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:1340
k @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:1612
(anonymous) @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:1622
load (async)
send @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:1622
ajax @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:1600
_makeRequest @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:11999
_makeRequest @ ghost.min-f890f42fd7ab049143bfb83e307e291e.js:1146
r @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:3952
request @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:11993
ajax @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:12026
r @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:3952
saveRecord @ ghost.min-f890f42fd7ab049143bfb83e307e291e.js:13
updateRecord @ ghost.min-f890f42fd7ab049143bfb83e307e291e.js:12
Ye @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:15544
flushPendingSave @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:15621
e.invoke @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:2410
e.flush @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:2403
e.flush @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:2415
e.end @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:2427
e._run @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:2468
e.run @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:2435
y @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:3071
(anonymous) @ ghost.min-f890f42fd7ab049143bfb83e307e291e.js:962
(anonymous) @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:8585
(anonymous) @ vendor.min-53d49a3c7e263c848106e1538838d3f3.js:8585

This is the Chrome HAR capture with the requests that lead up to the error:

It very easy for me to repro I still have another 150ish recently imported blog posts that exhibit this behavior.

I used the import feature to import my old blog. I can easily generate another one of those so you can test to your heart’s content.


I think that makes sense. It would be even better to be able to pinpoint the position, but I totally understand that may not be possible. I’d be pretty frustrated if people force that onto my backlog, but hey, we can have our desires ;).

Maybe if the top of the container is on screen, put the cursor on the top.

If the bottom of the container is on screen and the top isn’t, put the cursor at the bottom. If neither is on screen put it at the top?


Grammarly is not currently supported, it has conflicts with mobiledoc-kit’s MutationObservers. In 1.24.3 Grammarly will be disabled for the Koenig editor.

Hopefully it will be possible to add support at some point in the future but it will require an upstream fix - community help there would definitely be appreciated :smile:


Noticed another thing yesterday. When I put a Youtube Embed in a HTML card, it renders in edit mode just fine, but on my blog it disappears. i switched the card to Markdown and the video shows just fine.

It may be due to the fact that I’ve customized my theme and need to pull in the latest changes… But for those seeking a workaround, the markdown option works beautifully.


Hey, @Jesse_Houwing thank you for reporting this :slight_smile: . The issue is going to be fixed soon with the introduction of Embed cards. Until then your workaround - using markdown card - should be fine.


1.24.3 has been released with new Koenig features, bug fixes, and improvements (changelog since 1.24.0):

  • :sparkles: Embed card
  • :sparkles: Night Shift support
  • :bug: Fixed scroll jump when card is selected
  • :bug: Disable Grammarly to fix high CPU usage

Embed cards can be created more quickly by passing the URL as a parameter to the /-menu command. Eg:


Ooooh. Can’t wait to try. Is there a list of services supported somewhere?


Every service listed here should work, if you try one and it doesn’t work please let us know! :smile: https://oembed.com/providers.json

We’ll be creating a curated list of the biggest/most popular services to display in-app as a help modal in the future so that it’s more easily discoverable.


Just converted my Markdown youtube embed to the new embed card, but the video shows up as a 0x0 iframe and is ignored by Chrome. This is the rendered HTML:

<figure class="kg-embed-card"><iframe width="480" height="270" src="https://www.youtube.com/embed/SHOVVnRB4h0?feature=oembed" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></figure>

This is the public URL containing the post, right now it has both the MD and the Embed card active:


The New card window has become quite a bit longer, since my editing is usually at the bottom of the page, all of the embed cards are rendered off screen.


Is a Wide instead of deep card not better on desktop? Would you be able to render the card above instead of below in case it doesn’t fit on the viewport? Can you scroll so the card becomes visible as a whole?


I think, speaking to @Jesse_Houwing’s point, it might be a good idea to offer up the icons in more of a list format rather than an icon format, similar to how Slack or Alfred does it. I could see the sheer number of icons getting overwhelming as Koenig’s offerings grow.

It doesn’t have to be a default, but it might be worth considering, especially considering the way the slash commands play up muscle memory.

This is a cool feature, though, and really highlight’s Koenig’s long-term potential.


Unfortunately, the Embed card doesn’t render the video on the actual blog either. Woks great in the editor though :).


@Jesse_Houwing if you are using Casper then the relevant changes can be seen here, if you have a custom theme then you’ll need to update it accordingly.

Sorry, the Casper update was missed in the release, I’ll see if we can do a patch release tomorrow that includes the updated version of Casper.


That was my initial thinking. Thanks for confirming. I’ll need to work in the updated files then. I’m still on Casper so it should be easy. Is it just these css files that have changed?


Any news on this ✨ Koenig Editor - Beta Release?


I’ve not been able to replicate it so far :disappointed: Would you mind sending me an export of your site? DM on here or kevin@ghost.org. Maybe there’s something specific to the data that is causing a problem :thinking: