npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

sanity-plugin-markdown

v5.0.0

Published

Markdown fields in Sanity Studio. Supports Github flavored Markdown and image uploads.

Downloads

26,018

Readme

sanity-plugin-markdown

This is a Sanity Studio v3 plugin. For the v2 version, please refer to the v2-branch.

What is it?

A Markdown editor with preview for Sanity Studio.

Supports Github flavored markdown and image uploads. You can either drag image(s) into the editor or click the bottom bar to bring up a file selector. The resulting image URL(s) are inserted with a default width parameter which you can change to your liking using the Sanity image pipeline parameters.

The current version is a wrapper around React SimpleMDE (EasyMDE) Markdown Editor, and by extension, EasyMDE.

example.png

Installation

Install sanity-plugin-markdown and easymde@2 (peer dependency).

npm install --save sanity-plugin-markdown easymde@2

Usage

Add it as a plugin in sanity.config.ts (or .js):

import {markdownSchema} from 'sanity-plugin-markdown'

export default defineConfig({
  // ...
  plugins: [markdownSchema()],
})

Then, declare a field in your schema to be markdown

const myDocument = {
  type: 'document',
  name: 'myDocument',
  fields: [
    {
      type: 'markdown',
      description: 'A Github flavored markdown field with image uploading',
      name: 'bio',
    },
  ],
}

Next.js compatability

Next.js without Next 13 app directory does not support css imports from node_modules.

To use this plugin in this context (pages directory), use the sanity-plugin-markdown/next import instead of sanity-plugin-markdown:

import {markdownSchema} from 'sanity-plugin-markdown/next'

Then, make sure to add

import 'easymde/dist/easymde.min.css'

to the top of pages/_app.tsx.

Customizing the default markdown input editor

The plugin takes an input config option that can be used in combination with the MarkdownInput export to configure the underlying React SimpleMDE component:

  • Create a custom component that wraps MarkdownInput
  • Memoize reactMdeProps and pass along
// CustomMarkdownInput.tsx
import {MarkdownInput, MarkdownInputProps} from 'sanity-plugin-markdown'

export function CustomMarkdownInput(props) {
  const reactMdeProps: MarkdownInputProps['reactMdeProps'] = useMemo(() => {
    return {
      options: {
        toolbar: ['bold', 'italic'],
        // more options available, see:
        // https://github.com/Ionaru/easy-markdown-editor#options-list
      },
      // more props available, see:
      // https://github.com/RIP21/react-simplemde-editor#react-simplemde-easymde-markdown-editor
    }
  }, [])

  return <MarkdownInput {...props} reactMdeProps={reactMdeProps} />
}

Set the plugin input option:

// studio.config.ts
import {markdownSchema} from 'sanity-plugin-markdown'
import {CustomMarkdownInput} from './CustomMarkdownInput'

export default defineConfig({
  // ... rest of the config
  plugins: [markdownSchema({input: CustomMarkdownInput})],
})

Customize editor for a single field

Implement a custom input similar to the one above, and use it as components.input on the field directly.

defineField({
  type: 'markdown',
  name: 'markdown',
  title: 'Markdown',
  components: {input: CustomMarkdownInput},
})

Customizing editor preview

One way to customize the preview that does not involve ReactDOMServer (used by React SimpleMDE) is to install marked and DOMPurify and create a custom preview:

npm i marked dompurify

Then use these to create a custom editor:

// MarkdownInputCustomPreview.tsx
import {MarkdownInput, MarkdownInputProps} from 'sanity-plugin-markdown'
import DOMPurify from 'dompurify'
import {marked} from 'marked'

export function CustomMarkdownInput(props) {
  const reactMdeProps: MarkdownInputProps['reactMdeProps'] = useMemo(() => {
    return {
      options: {
        previewRender: (markdownText) => {
          // configure as needed according to
          // https://github.com/markedjs/marked#docs
          return DOMPurify.sanitize(marked.parse(markdownText))
        },
        //customizing using renderingConfig is also an option
      },
    }
  }, [])

  return <MarkdownInput {...props} reactMdeProps={reactMdeProps} />
}

Use the component as described in previous sections.

Custom image urls

Provide a function to options.imageUrl that takes a SanityImageAssetDocument and returns a string.

The function will be invoked whenever an image is pasted or dragged into the markdown editor, after upload completes.

The default implementation uses

;(imageAsset) => `${imageAsset.url}?w=450`

Example imageUrl option

defineField({
  type: 'markdown',
  name: 'markdown',
  title: 'Markdown',
  options: {
    imageUrl: (imageAsset) => `${imageAsset.url}?w=400&h=400`,
  },
})

License

MIT-licensed. See LICENSE.

Develop & test

This plugin uses @sanity/plugin-kit with default configuration for build & watch scripts.

See Testing a plugin in Sanity Studio on how to run this plugin with hotreload in the studio.

Release new version

Run "CI & Release" workflow. Make sure to select the main branch and check "Release new version".

Semantic release will only release on configured branches, so it is safe to run release on any branch.