{"id":13468539,"url":"https://github.com/kevin940726/remark-codesandbox","last_synced_at":"2025-04-05T04:15:06.610Z","repository":{"id":38428088,"uuid":"234520880","full_name":"kevin940726/remark-codesandbox","owner":"kevin940726","description":"🎩  Create CodeSandbox directly from code blocks","archived":false,"fork":false,"pushed_at":"2022-06-03T22:59:58.000Z","size":3435,"stargazers_count":283,"open_issues_count":5,"forks_count":13,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-27T17:01:46.332Z","etag":null,"topics":["codesandbox","docz","gatsby","hacktoberfest","mdx","remark","remark-plugin","storybook-addon-docs"],"latest_commit_sha":null,"homepage":"https://codesandbox.io/s/github/kevin940726/remark-codesandbox/tree/master/fixtures/demo?autoresize=1\u0026fontsize=14\u0026hidenavigation=1\u0026module=%2Fsrc%2Findex.md\u0026theme=dark","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kevin940726.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-01-17T09:57:04.000Z","updated_at":"2025-03-18T13:27:57.000Z","dependencies_parsed_at":"2022-09-01T04:31:12.431Z","dependency_job_id":null,"html_url":"https://github.com/kevin940726/remark-codesandbox","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kevin940726%2Fremark-codesandbox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kevin940726%2Fremark-codesandbox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kevin940726%2Fremark-codesandbox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kevin940726%2Fremark-codesandbox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kevin940726","download_url":"https://codeload.github.com/kevin940726/remark-codesandbox/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247043342,"owners_count":20874086,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["codesandbox","docz","gatsby","hacktoberfest","mdx","remark","remark-plugin","storybook-addon-docs"],"created_at":"2024-07-31T15:01:13.107Z","updated_at":"2025-04-05T04:15:06.576Z","avatar_url":"https://github.com/kevin940726.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# remark-codesandbox\n\n🎩 A [remark](https://remark.js.org/) plugin to create [CodeSandbox](https://codesandbox.io/) directly from code blocks\n\n[![npm version](https://badge.fury.io/js/remark-codesandbox.svg)](https://badge.fury.io/js/remark-codesandbox)\n\n\u003cimg src=\"demo.png\" alt=\"Demo transformation\" width=\"400\" /\u003e\n\n**Try it online on CodeSandbox!** (Yep, we're demoing CodeSandbox inside CodeSandbox, why not!?)\n\n[![Edit remark-codesandbox demo](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/kevin940726/remark-codesandbox/tree/master/fixtures/demo?autoresize=1\u0026fontsize=14\u0026hidenavigation=1\u0026module=%2Fsrc%2Findex.md\u0026theme=dark)\n\n## Features\n\n- [x] 🔗 Directly create CodeSandbox urls from code blocks\n- [x] ✨ Support 3 different _modes_: **meta**, **iframe**, and **button**\n- [x] 🚀 Don't need to create additional folders or `package.json` file\n- [x] 🎉 Support [MDX](https://mdxjs.com/), [Gatsby](https://www.gatsbyjs.org/), [Storybook Docs](https://storybook.js.org/docs/basics/introduction/), [docz](https://www.docz.site/), etc...\n- [x] 📦 Support bringing your own custom templates, even directly from the same repository!\n- [x] ⚡ One line setup, highly customizable\n- [x] 💪 Great for library authors to demonstrate usages directly from documentation!\n\n## Examples\n\n- [**`reaviz`**](https://reaviz.io/?path=/docs/docs-chart-types-area-chart--page) documentation is built with [Storybook docs](https://github.com/storybookjs/storybook/tree/master/addons/docs#manual-configuration) and `remark-codesandbox`.\n- The [**test cases**](https://github.com/kevin940726/remark-codesandbox/blob/master/packages/remark-codesandbox/test.js) of this project.\n\n## Installation\n\n```bash\nyarn add -D remark-codesandbox\n```\n\n## Getting Started\n\nImport `remark-codesandbox` to your remark plugins.\n\n```js\nconst codesandbox = require('remark-codesandbox');\n```\n\n[**remark**](https://github.com/remarkjs/remark/blob/master/doc/plugins.md#using-plugins)\n\n```js\nremark().use(codesandbox, { mode: 'button' });\n```\n\n[**MDX**](https://mdxjs.com/advanced/plugins#using-remark-and-rehype-plugins)\n\n```js\nmdx(mdxCode, {\n  remarkPlugins: [[codesandbox, { mode: 'button' }]],\n});\n```\n\n[**Gatsby (gatsby-plugin-mdx)**](https://www.gatsbyjs.org/docs/mdx/plugins/#remark-plugins)\n\nUse the `/gatsby` endpoint to use the Gatsby's version of the plugin.\n\n```js\nmodule.exports = {\n  plugins: [\n    {\n      resolve: 'gatsby-plugin-mdx',\n      options: {\n        gatsbyRemarkPlugins: [\n          {\n            resolve: 'remark-codesandbox/gatsby',\n            options: {\n              mode: 'button',\n            },\n          },\n        ],\n      },\n    },\n  ],\n};\n```\n\n[**Gatsby (gatsby-transformer-remark)**](https://www.gatsbyjs.org/packages/gatsby-transformer-remark)\n\nUse the `/gatsby` endpoint to use the Gatsby's version of the plugin.\n\n```js\nmodule.exports = {\n  plugins: [\n    {\n      resolve: 'gatsby-transformer-remark',\n      options: {\n        plugins: [\n          {\n            resolve: 'remark-codesandbox/gatsby',\n            options: {\n              mode: 'button',\n            },\n          },\n        ],\n      },\n    },\n  ],\n};\n```\n\n[**Storybook docs**](https://github.com/storybookjs/storybook/tree/master/addons/docs#manual-configuration)\n\n```js\nconfig.module.rules.push({\n  test: /\\.(stories|story)\\.mdx$/,\n  use: [\n    {\n      loader: '@mdx-js/loader',\n      options: {\n        compilers: [createCompiler({})],\n        remarkPlugins: [[codesandbox, { mode: 'button' }]],\n      },\n    },\n  ],\n});\n```\n\n## Usage\n\nAdd a special _meta tag_ to your code blocks.\n\n````md\n```js codesandbox=react\nimport React from 'react';\nimport ReactDOM from 'react-dom';\n\nReactDOM.render(\n  \u003ch1\u003eHello remark-codesandbox!\u003c/h1\u003e,\n  document.getElementById('root')\n);\n```\n````\n\nAnd..., that's it!\n\nThe 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!\n\nThere are also other **modes** and additional configurations, follow the [documentation](#documentation) below for more information.\n\n## Documentation\n\n### Markdown Syntax\n\nAppend `codesandbox` meta to code blocks to enable `remark-codesandbox`. The value here is the `id` of the sandbox.\n\n````md\n```js codesandbox=new\n// ...\n```\n````\n\nThere are a set of default official sandbox templates, you can find the list [here](https://codesandbox.io/api/v1/sandboxes/templates/official). Some examples are [`new`(react)](https://codesandbox.io/s/new), [`vanilla`(parcel)](https://codesandbox.io/s/vanilla), [`vue`](https://codesandbox.io/s/vue), [`static`](https://codesandbox.io/s/static)...\n\nThe 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.\n\nThere 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.\n\n````md\n```js codesandbox=react-component\nimport React from 'react';\n\nexport default function App() {\n  return \u003ch1\u003eHello remark-codesandbox!\u003c/h1\u003e;\n}\n```\n````\n\nIt'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).\n\n````md\n```js codesandbox=mqpp1d4r0\n// ...\n```\n````\n\nWant 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.\n\nAs in the other examples, the content of the code block will replace the entry file in the template.\n\n````md\n```js codesandbox=file:./templates/vanilla-console\nconsole.log('this code will replace the entry file content');\n```\n````\n\nThe path is too long to type every time? Consider creating it as a [custom template](#customTemplates). It's also the recommended way!\n\n\u003e Pro tip: You can create file templates directly on [codesandbox.io/s](https://codesandbox.io/s) and download them by selecting `File` -\u003e `Export to ZIP` in the menu bar. Unzip it somewhere and... Abrahadabra! You got yourself a file template!\n\n### Query params\n\nIt's also possible to customize the url by appending _query parameters_. Just append them after the sandbox id. All [options](https://codesandbox.io/docs/embedding#embed-options) are allowed.\n\n````md\n```js codesandbox=new?codemirror=1\u0026fontsize=12\n// ...\n```\n````\n\nThere 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.\n\n#### `entry`\n\nA special query param `entry` is introduced to allow you to override the specific file with the contents of the code block.\n\n````md\n```js codesandbox=new?entry=src/App.js\n// Override `src/App.js` rather than the default `src/index.js` with this contents of the code block\n```\n````\n\n#### `overrideEntry`\n\nBy 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`.\n\nSet `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.\n\n````md\n```js codesandbox=react?overrideEntry=4-12\nReactDOM.render(\n  \u003ch1\u003eHello remark-codesandbox!\u003c/h1\u003e,\n  document.getElementById('root')\n);\n```\n````\n\nWith this tip, you can avoid passing unrelated code into the code block, so that the readers can focus on what really matters.\n\nThere'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.\n\n````md\n```js codesandbox=react?overrideEntry=4-\nReactDOM.render(\n  \u003ch1\u003eHello remark-codesandbox!\u003c/h1\u003e,\n  document.getElementById('root')\n);\n```\n````\n\nIf you would like to use the template as-is without any of the content of the code block, add the `?overrideEntry=false` query string:\n\n````md\n```js codesandbox=file:./templates/vanilla-console?overrideEntry=false\n// This code will not be added to the sandbox\n```\n````\n\n#### `style`\n\nYou can also override the default style used in the **iframe** mode.\n\n````md\n```js codesandbox=react?style=height:1000px\n// The generated iframe will have height of 1000px instead of the default 500px\n```\n````\n\nYou 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;`).\n\n````md\n```js codesandbox=react?style=height:1000px;width:600px;\n// The result style will be: \"width:600px; height:1000px; border:0; border-radius:4px; overflow:hidden;\"\n```\n````\n\n### Options\n\nThe plugin accepts a set of options with the following default values:\n\n```ts\n{\n  remarkPlugins: [\n    codesandbox,\n    {\n      // Can be one of `meta`, `iframe`, or `button`\n      mode: 'meta',\n      // The query here will be appended to the generated url for every sandbox. Can be `string`, `object`, `URLSearchParams` instance, or `undefined`\n      query:\n        mode === 'iframe'\n          ? {\n              fontsize: '14px',\n              hidenavigation: 1,\n              theme: 'dark',\n            }\n          : undefined,\n      // Define custom templates or override existing ones\n      customTemplates: {},\n      // Whether to automatically deploy code blocks via CodeSandbox API\n      autoDeploy: false,\n    },\n  ];\n}\n```\n\n### `mode`\n\n- `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.\n- `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`.\n- `button`: This mode will keep the code block as is, and append a **CodeSandbox button** like the one below immediately after the code block.\n\n  [![Edit React](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-new?fontsize=14\u0026hidenavigation=1\u0026theme=dark)\n\n### `query`\n\nBy 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.\n\n```js\nquery =\n  mode === 'iframe'\n    ? {\n        fontsize: '14px',\n        hidenavigation: 1,\n        theme: 'dark',\n      }\n    : undefined;\n```\n\nYou 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.\n\n### `customTemplates`\n\nDefine 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.\n\nThe template info is an object with the interface below.\n\n```js\ninterface TemplateInfo {\n  extends: string;\n  entry?: string;\n  query?: string | { [key: string]: string } | URLSearchParams;\n  files?: { [filePath: string]: { content: string | Object } };\n}\n```\n\n- `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.\n- `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.\n- `query`: The query params to be appended to the generated url. It will _merge_ and override and key in the [`options.query`](#query) above. However, it will be merged and overridden by the query defining inline in the code block meta.\n- `files`: Additional files to merge and override the existing ones. The signature follows the [official API](https://codesandbox.io/docs/importing#how-it-works). It's recommended to use the `file:` path in `extends` field whenever possible as it's easier to manage and version control.\n\nBelow is the default custom templates.\n\n```js\n{\n  // Alias `react` to `new`\n  react: {\n    extends: 'new',\n  },\n  // Alias `react-component` to `new`, but also override `entry` to `src/App.js`\n  'react-component': {\n    extends: 'new',\n    entry: 'src/App.js',\n  },\n}\n```\n\n### `autoDeploy`\n\nBy default, the url is generated locally without calling the [official API](https://codesandbox.io/docs/importing#define-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](https://stackoverflow.com/a/417184/4699228) to keep urls under 2000 characters, longer urls might not work in some browsers.\n\nYou 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.\n\nA 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.\n\n```js\n{\n  autoDeploy: process.env.NODE_ENV === 'production';\n}\n```\n\n## Contributing\n\nRun `git clone` and `cd`.\n\n```bash\nyarn # Install dependencies\n\nyarn test # Run tests\n\nyarn example # Run build on all examples\n\nyarn bump [patch|minor|major] # Bump version of remark-codesandbox\n\nyarn release # Publish remark-codesandbox to npm\n```\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkevin940726%2Fremark-codesandbox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkevin940726%2Fremark-codesandbox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkevin940726%2Fremark-codesandbox/lists"}