Skip to content

feat(stories): enable rich text in story editor#1327

Open
garcia5 wants to merge 2 commits intomasterfrom
feat/rich-editor
Open

feat(stories): enable rich text in story editor#1327
garcia5 wants to merge 2 commits intomasterfrom
feat/rich-editor

Conversation

@garcia5
Copy link
Collaborator

@garcia5 garcia5 commented Dec 19, 2025

  • add TipTap dependency (and some extensions) to frontend
  • replace TextArea component with custom TipTapEditor component for story editing
    • supports inline markdown + automatic links
    • links are created with rel="noopener noreferrer nofollow" target="_blank" attributes by default, see Link extension docs
    • saves stories as html text
  • use TipTapEditor with editing disabled to render story html in Story component

@garcia5 garcia5 self-assigned this Dec 19, 2025
@garcia5 garcia5 added enhancement New feature or request javascript Pull requests that update Javascript code labels Dec 19, 2025
Copy link
Owner

@jboolean jboolean left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for trying this out! I'm seeing some immediate problems on the preview branch

  1. The overflow behavior of the editor changed

Here it is before:

https://github.com/user-attachments/assets/70fc90fd-c0a3-4957-b581-3ee975223df9
And now:
https://github.com/user-attachments/assets/577bba55-9703-4a2a-8d8a-036126e37887

I tried to render an existing story with a url in it to see if the url worked (photo: nynyma_rec0040_1_00998_0026).
Rendering before:
image

Rendering now:
image

The url is not clickable and the line breaks are missing.

I noticed that it persists in html rather than markdown. I think Markdown is a better choice here

  • It is a much simpler format. We only needs links and basic formatting. Html is overly complex for our needs.
  • Markdown is a simple, human readable format. Persisted content where the user has not added any formatting is cluttered with p tags.
  • Markdown is backwards compatible with plaintext. Meaning, the plaintext content we already have can be rendered as markdown. Especially if users used links, they can be rendered, as can basic formatting like underscores and asterisks.
  • Not a trap door. A markdown renderer can be removed and the content still looks good. HTML would require a migration.
  • Security. I'm sure tiptap renderer has xss mitigations, but it still makes me nervous about what happens if a story is submitted (especially bypassing the editor) with script tags, images, etc. I feel more confident in React's built-in escapes that are currently used on the plaintext content. fwiw I did try to put it script and img tags and the tiptap renderer stripped them out, and the header rendered as a p.

I see tiptap does support markdown to some extent.
I think it's also worth looking at react-markdown for rendering. If you enable the gfm (Github flavored markdown) plugin in react-markdown it appears to enable auto-linking. It also support allow-listing tags.

@garcia5
Copy link
Collaborator Author

garcia5 commented Jan 4, 2026

Thanks for trying this out! I'm seeing some immediate problems on the preview branch

  1. The overflow behavior of the editor changed

Here it is before:

https://github.com/user-attachments/assets/70fc90fd-c0a3-4957-b581-3ee975223df9 And now: https://github.com/user-attachments/assets/577bba55-9703-4a2a-8d8a-036126e37887

I tried to render an existing story with a url in it to see if the url worked (photo: nynyma_rec0040_1_00998_0026). Rendering before: image

Rendering now: image

The url is not clickable and the line breaks are missing.

I noticed that it persists in html rather than markdown. I think Markdown is a better choice here

  • It is a much simpler format. We only needs links and basic formatting. Html is overly complex for our needs.
  • Markdown is a simple, human readable format. Persisted content where the user has not added any formatting is cluttered with p tags.
  • Markdown is backwards compatible with plaintext. Meaning, the plaintext content we already have can be rendered as markdown. Especially if users used links, they can be rendered, as can basic formatting like underscores and asterisks.
  • Not a trap door. A markdown renderer can be removed and the content still looks good. HTML would require a migration.
  • Security. I'm sure tiptap renderer has xss mitigations, but it still makes me nervous about what happens if a story is submitted (especially bypassing the editor) with script tags, images, etc. I feel more confident in React's built-in escapes that are currently used on the plaintext content. fwiw I did try to put it script and img tags and the tiptap renderer stripped them out, and the header rendered as a p.

I see tiptap does support markdown to some extent. I think it's also worth looking at react-markdown for rendering. If you enable the gfm (Github flavored markdown) plugin in react-markdown it appears to enable auto-linking. It also support allow-listing tags.

Thanks for finding a good story for testing compatibility, I was having a hard time finding something more complex to see how tiptap would handle it. I mostly reached for Tiptap because it's a library I have experience using :D I'll take a look at react-markdown, thanks for the thorough feedback!

- use `Markdown` component from react-markdown to convert markdown text -> HTML nodes
- limit to only basic elements, no headings, strikethroughs, etc. allowed
- add logic to automatically transform plain URLs into markdown links when story is rendered
- add custom <a> tag implementation for react-markdown to make sure links always open in new tabs
@garcia5
Copy link
Collaborator Author

garcia5 commented Jan 17, 2026

Sorry for the delay here @jboolean!

Reworked this to be a lot more simple and use just react-markdown. Looks to be working with the example story you mentioned and I added in some basic auto linking functionality without including the gfm package.

image

I'm kind of torn on whether or not I should add to the TextContent placeholder text to indicate that markdown is supported, any feelings one way or another? I think it's probably better to leave the placeholder as-is to not confuse people who don't know what markdown is, but also could encourage nicer story formatting if people know it's supported.

Any thoughts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request javascript Pull requests that update Javascript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants