Marked is a js package to parse markdown.

You can use it as a lightweight approach to display markdown in your app.

1. Parse to markdown while typing #

markedjs - input form with markdown output

# Terminal
bin/rails g scaffold messages content:text
bin/rails g stimulus markdown
bin/rails g stimulus markdown-display
# using importmaps
bin/importmap pin marked
# or using jsbundling
yarn add marked
# views/messages/_form.html.erb
<div data-controller="markdown">
  <%= form.text_area :content, rows: 15, data: { action: "keyup->markdown#change", markdown_target: "input" } %>
  <div data-markdown-target="output">
</div>
// javascript/controllers/markdown_controller.js
import { Controller } from "@hotwired/stimulus"
import { marked } from "marked"

// Connects to data-controller="markdown"
export default class extends Controller {
  static targets = ["input", "output"]

  connect() {
    this.parse()
  }

  change() {
    this.parse()
  }

  parse() {
    this.outputTarget.innerHTML = marked.parse(this.inputTarget.value)
  }
}

2. Parse html to markdown on page load #

markedjs - parse html to markdown on page load

# views/messages/_message.html.erb
<%= content_tag :div, message.content, data: { controller: "markdown-display" } %>
# javascript/controllers/markdown_display_controller.js
import { Controller } from "@hotwired/stimulus"
import { marked } from "marked"

// Connects to data-controller="markdown-display"
export default class extends Controller {
  connect() {
    this.element.innerHTML = marked.parse(this.element.innerHTML)
  }
}

Full credit to source. I’ve added the solution on my blog primarily in case I lose access to the authors content.


🤔 However at some point you might want to have more control of the rendered markdown.

Than you will want to use:

  1. gem redcarpet to parse markdown
  2. gem rouge to style programming language syntax
  3. live previews with hotwire to render the output as you type
  4. StimulusJS textarea autogrow to grow your input area as you type