• Stars
    star
    275
  • Rank 149,796 (Top 3 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created almost 5 years ago
  • Updated over 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

🎩 Create CodeSandbox directly from code blocks

remark-codesandbox

🎩 A remark plugin to create CodeSandbox directly from code blocks

npm version

Demo transformation

Try it online on CodeSandbox! (Yep, we're demoing CodeSandbox inside CodeSandbox, why not!?)

Edit remark-codesandbox demo

Features

  • πŸ”— Directly create CodeSandbox urls from code blocks
  • ✨ Support 3 different modes: meta, iframe, and button
  • πŸš€ Don't need to create additional folders or package.json file
  • πŸŽ‰ Support MDX, Gatsby, Storybook Docs, docz, etc...
  • πŸ“¦ Support bringing your own custom templates, even directly from the same repository!
  • ⚑ One line setup, highly customizable
  • πŸ’ͺ Great for library authors to demonstrate usages directly from documentation!

Examples

Installation

yarn add -D remark-codesandbox

Getting Started

Import remark-codesandbox to your remark plugins.

const codesandbox = require('remark-codesandbox');

remark

remark().use(codesandbox, { mode: 'button' });

MDX

mdx(mdxCode, {
  remarkPlugins: [[codesandbox, { mode: 'button' }]],
});

Gatsby (gatsby-plugin-mdx)

Use the /gatsby endpoint to use the Gatsby's version of the plugin.

module.exports = {
  plugins: [
    {
      resolve: 'gatsby-plugin-mdx',
      options: {
        gatsbyRemarkPlugins: [
          {
            resolve: 'remark-codesandbox/gatsby',
            options: {
              mode: 'button',
            },
          },
        ],
      },
    },
  ],
};

Gatsby (gatsby-transformer-remark)

Use the /gatsby endpoint to use the Gatsby's version of the plugin.

module.exports = {
  plugins: [
    {
      resolve: 'gatsby-transformer-remark',
      options: {
        plugins: [
          {
            resolve: 'remark-codesandbox/gatsby',
            options: {
              mode: 'button',
            },
          },
        ],
      },
    },
  ],
};

Storybook docs

config.module.rules.push({
  test: /\.(stories|story)\.mdx$/,
  use: [
    {
      loader: '@mdx-js/loader',
      options: {
        compilers: [createCompiler({})],
        remarkPlugins: [[codesandbox, { mode: 'button' }]],
      },
    },
  ],
});

Usage

Add a special meta tag to your code blocks.

```js codesandbox=react
import React from 'react';
import ReactDOM from 'react-dom';

ReactDOM.render(
  <h1>Hello remark-codesandbox!</h1>,
  document.getElementById('root')
);
```

And..., that's it!

The above example with mode being set to button will append a CodeSandbox button after the code block. Clicking on it will open the generated sandbox. How cool is that!

There are also other modes and additional configurations, follow the documentation below for more information.

Documentation

Markdown Syntax

Append codesandbox meta to code blocks to enable remark-codesandbox. The value here is the id of the sandbox.

```js codesandbox=new
// ...
```

There are a set of default official sandbox templates, you can find the list here. Some examples are new(react), vanilla(parcel), vue, static...

The content of the code block will replace the entry file entirely. So for the new template, the content will replace the src/index.js file entirely. Be sure to import the necessary packages for the templates to work.

There are also some default alias provided by the plugin. react is an alias to new. react-component is also an alias to new but changing the entry to src/App.js. So that you can just export a react component in the code block.

```js codesandbox=react-component
import React from 'react';

export default function App() {
  return <h1>Hello remark-codesandbox!</h1>;
}
```

It's also possible to use any existing sandbox. Just get the id of the sandbox from the url. The id is usually the last ~5 random characters of the sandbox url. Sandbox imported from Github is also supported, the id is usually the sub-domain of the sandbox preview url (~10 random characters).

```js codesandbox=mqpp1d4r0
// ...
```

Want to use custom templates and keep them version controlled in the same repository? Use file: schema to load templates directly from the file system! The below code will load the template from the path ./templates/vanilla-console, relative to the markdown file. The file templates are directories with at least a package.json file inside.

As in the other examples, the content of the code block will replace the entry file in the template.

```js codesandbox=file:./templates/vanilla-console
console.log('this code will replace the entry file content');
```

The path is too long to type every time? Consider creating it as a custom template. It's also the recommended way!

Pro tip: You can create file templates directly on codesandbox.io/s and download them by selecting File -> Export to ZIP in the menu bar. Unzip it somewhere and... Abrahadabra! You got yourself a file template!

Query params

It's also possible to customize the url by appending query parameters. Just append them after the sandbox id. All options are allowed.

```js codesandbox=new?codemirror=1&fontsize=12
// ...
```

There are several special query params you can set inline. All the special query params below will not be passed to the generated CodeSandbox URL, as they are not officially supported.

entry

A special query param entry is introduced to allow you to override the specific file with the contents of the code block.

```js codesandbox=new?entry=src/App.js
// Override `src/App.js` rather than the default `src/index.js` with this contents of the code block
```

overrideEntry

By default, contents in the code block will override all the contents in the entry file. You can change this by setting the special query param overrideEntry.

Set overrideEntry to a range of line numbers to specify which part of the entry file you want the code block to override. The below example will replace the entry file of the react template (src/index.js) from line 4 to 12 with the contents in the code block.

```js codesandbox=react?overrideEntry=4-12
ReactDOM.render(
  <h1>Hello remark-codesandbox!</h1>,
  document.getElementById('root')
);
```

With this tip, you can avoid passing unrelated code into the code block, so that the readers can focus on what really matters.

There's a handy shortcut to only specify the start line without the end line to replace the whole entry file starting from a specific line number without knowing how long it is.

```js codesandbox=react?overrideEntry=4-
ReactDOM.render(
  <h1>Hello remark-codesandbox!</h1>,
  document.getElementById('root')
);
```

If you would like to use the template as-is without any of the content of the code block, add the ?overrideEntry=false query string:

```js codesandbox=file:./templates/vanilla-console?overrideEntry=false
// This code will not be added to the sandbox
```

style

You can also override the default style used in the iframe mode.

```js codesandbox=react?style=height:1000px
// The generated iframe will have height of 1000px instead of the default 500px
```

You can pass in multiple styles separated by ;. All styles will merge and override the default styles (width:100%; height:500px; border:0; border-radius:4px; overflow:hidden;).

```js codesandbox=react?style=height:1000px;width:600px;
// The result style will be: "width:600px; height:1000px; border:0; border-radius:4px; overflow:hidden;"
```

Options

The plugin accepts a set of options with the following default values:

{
  remarkPlugins: [
    codesandbox,
    {
      // Can be one of `meta`, `iframe`, or `button`
      mode: 'meta',
      // The query here will be appended to the generated url for every sandbox. Can be `string`, `object`, `URLSearchParams` instance, or `undefined`
      query:
        mode === 'iframe'
          ? {
              fontsize: '14px',
              hidenavigation: 1,
              theme: 'dark',
            }
          : undefined,
      // Define custom templates or override existing ones
      customTemplates: {},
      // Whether to automatically deploy code blocks via CodeSandbox API
      autoDeploy: false,
    },
  ];
}

mode

  • meta: Generate the CodeSandbox url and store them in the AST. By itself this mode won't have any visual change to the markdown, it's useful for other plugins or users to kick in and do whatever they like with the sandbox url. The url will be stored in node.data.codesandboxUrl and node.data.hProperties.dataCodesandboxUrl. One example usage would be to customize the CodeSandbox button in the UI.

  • iframe: This mode will replace the code block entirely with the generated sandbox iframe tag. The iframe comes with some default query params, but you can override them via iframeQuery.

  • button: This mode will keep the code block as is, and append a CodeSandbox button like the one below immediately after the code block.

    Edit React

query

By default there will be no query except for the module key appended to the generated url. You can customize query in every url here. However, when the mode is iframe, there will be a set of custom queries predefined below.

query =
  mode === 'iframe'
    ? {
        fontsize: '14px',
        hidenavigation: 1,
        theme: 'dark',
      }
    : undefined;

You can override them by passing query to the options. Note that the object passed will replace the default object, be sure to include the default query again if you want to keep them.

customTemplates

Define custom templates to use in the code blocks. Expect an object with the key being the template ID and the value is the template info.

The template info is an object with the interface below.

interface TemplateInfo {
  extends: string;
  entry?: string;
  query?: string | { [key: string]: string } | URLSearchParams;
  files?: { [filePath: string]: { content: string | Object } };
}
  • extends: To make defining custom templates easier, the plugin accepts a extends key to let you extend any existing template. The value can be any CodeSandbox id, or a file: path, or any other custom template id. If using file: paths, it's recommended to use absolute paths. Relative paths are relative to process.cwd() by default, in contrast to relative paths defining inline in the code blocks.
  • entry: The entry file to show in the template, it's also the file where the code block will replace to. Allowing users to use the same template/sandbox with a different file to override.
  • query: The query params to be appended to the generated url. It will merge and override and key in the options.query above. However, it will be merged and overridden by the query defining inline in the code block meta.
  • files: Additional files to merge and override the existing ones. The signature follows the official API. It's recommended to use the file: path in extends field whenever possible as it's easier to manage and version control.

Below is the default custom templates.

{
  // Alias `react` to `new`
  react: {
    extends: 'new',
  },
  // Alias `react-component` to `new`, but also override `entry` to `src/App.js`
  'react-component': {
    extends: 'new',
    entry: 'src/App.js',
  },
}

autoDeploy

By default, the url is generated locally without calling the official API. The API would only be called when the user clicks the button or views the iframe. This is done by manually construct the parameters locally, and compress them via lz-string. Note that there is a general guideline to keep urls under 2000 characters, longer urls might not work in some browsers.

You can bypass this by passing true to autoDeploy. Results in a much shorter url with an unique codesandbox_id in the url. The drawback is that it takes more time to generate the url.

A common practice would be to only set it to true in production (or when the result urls are too long for the browsers you support), while keeping it false when developing for faster reload time.

{
  autoDeploy: process.env.NODE_ENV === 'production';
}

Contributing

Run git clone and cd.

yarn # Install dependencies

yarn test # Run tests

yarn example # Run build on all examples

yarn bump [patch|minor|major] # Bump version of remark-codesandbox

yarn release # Publish remark-codesandbox to npm

License

MIT

More Repositories

1

BeanfunLogin

New Beanfun OTP login
C#
128
star
2

emoji-cz

✨ A commitizen emoji adapter.
JavaScript
64
star
3

remark-code-import

πŸ“ Populate code blocks from files
TypeScript
62
star
4

dcard-clone

Unofficial Dcard clone web application
JavaScript
60
star
5

minesweeper

The most complete minesweeper game built with React, Redux and Immutable.js.
JavaScript
57
star
6

nyan-progress

Nyan cat progress bar in Node, why not?
JavaScript
45
star
7

next-dynamic-loading-props

Pass props to the loading components in next/dynamic
TypeScript
11
star
8

kaihao.dev

Personal website and blog
MDX
8
star
9

eslint-plugin-no-mixed-operators

Fixable no-mixed-operators rule for eslint
JavaScript
7
star
10

shy-watch-face

Shy Garmin vΓ­voactive 4S watch face
Java
7
star
11

remarkbelow

Yet another markdown editor built with React, Electron, draft.js.
JavaScript
6
star
12

console-testing-library

πŸ“ Testing console the right way
JavaScript
4
star
13

slack-blockx

jsx for Slack block-kit
TypeScript
4
star
14

unbiased-github

JavaScript
4
star
15

svg-css-modules-loader

webpack loader to transform svg css modules
JavaScript
4
star
16

dailyjack

Pay respect to __Jack daily
JavaScript
4
star
17

sharing-validator

πŸ€“ Validate best practices for social sharing URLs
JavaScript
4
star
18

canopic

JavaScript
3
star
19

RottenCrawler

Fetch Rotten Tomatoes Data without an API key.
Python
3
star
20

muzier-cli

The muzier command line interface to download mp3 from Youtube and SoundCloud.
JavaScript
3
star
21

role-selector

Accessible role selector for Playwright, Puppeteer, jsdom, and browsers.
TypeScript
3
star
22

gulp-ftp-git

ftp upload on git push to remote server with gulp
JavaScript
3
star
23

to-gatsby-remark-plugin

Convert remark plugins to gatsby remark plugins.
JavaScript
3
star
24

fs-codesandboxer

Create CodeSandbox from file system
JavaScript
2
star
25

contributions

View the Github contributions of a user
JavaScript
2
star
26

define-messages

πŸ’¬ define intl messages done right
JavaScript
2
star
27

refined-slack

πŸ”“ Unlock Slack with full power
JavaScript
2
star
28

hot-watch

πŸ”₯πŸ‘€ Watch files and hot reload them
JavaScript
2
star
29

sproutChart

pie and bar chart fancy transition with D3.js.
JavaScript
2
star
30

react-step-by-step

React step-by-step tutorial of building a TODO app with best practice in 8 simple steps.
JavaScript
2
star
31

coverbadge

πŸ’― Create a coverage badge without any service provider.
JavaScript
2
star
32

challenges

πŸ€” Accept your next challenge
JavaScript
1
star
33

puppeteer-testing-library

Custom queries and Jest matchers for Puppeteer and Playwright with enforced best practices
TypeScript
1
star
34

playwright-headless-webkit-data-transfer-custom-type

TypeScript
1
star
35

drawful

[WIP] A Drawful clone built with React.
JavaScript
1
star
36

prettier-diff

πŸ‘€ View prettified diff online
TypeScript
1
star
37

node-slack-issue-linker

πŸ‘‰ Give me the links of the issues!
JavaScript
1
star
38

tiny-jack

A dedicate bot for Underground Discord server
JavaScript
1
star
39

slack-poker

Planning poker directly on Slack
TypeScript
1
star
40

ArduinoLEDMonitor

NTU NASA final project, using Intel Galileo Gen 2 and Arduino to monitor servers, display with LED.
Arduino
1
star
41

DcardSearcher

Search Dcard's contents like a charm.
JavaScript
1
star
42

get-codesandbox

Given a CodeSandbox id, GitHub path, or file system path, returns the contents of the sandbox
JavaScript
1
star