GithubHelp home page GithubHelp logo

elboman / gatsby-remark-embedded-codesandbox Goto Github PK

View Code? Open in Web Editor NEW
32.0 3.0 8.0 766 KB

A Gatsby Remark plugin for embedding Codesandbox given a folder of files

License: MIT License

JavaScript 100.00%
gatsby gatsbyjs gatsby-plugin gatsby-remark codesandbox embedded

gatsby-remark-embedded-codesandbox's Introduction

gatsby-remark-embedded-codesandbox

NPM badge Travis badge

This plugin adds support for generating embedded CodeSandbox, specifying a folder in local files to populate the contents of it. This enables example code to be stored along side of, and revisioned with, your website content.

This plugin is based on gatsby-remark-code-repls.

Getting started

To embed a CodeSandbox editor in you Markdown/remark content, simply add a link with the custom protocol pointing to the folder desired folder:

[embedded example](embedded-codesandbox://example/folder)

It will scan the folder and generate the proper html to include the editor.

Overview

For example, given the following project directory structure:

examples/
├── hello-world-example
│   ├── package.json
│   ├── index.html
│   └── index.js
├── some-other-example
│   ├── package.json
│   └── index.js

These example files can be referenced via links in Markdown that get transformed to embedded editors. For example:

<!-- before -->

[hello world example](embedded-codesandbox://hello-world-example)

<!-- after -->

<iframe src="https://codesandbox.io/api/v1/sandboxes/define?embed=1&parameters=N4IgZglgNgpgziAXKADgQwMYGs0HMYB0AVnAPYB2SoGFALjObVSOWgLYxIgwAe7KsEAF8hAGhARyAE14EAFrTZRmNRgyaIQAHgVKAfFoBGpKQE8DAemNnLuqHuHjJMnsQTIQq-oy6q4tAAIwUlIAgF4AgB0QQzQAJ2iAbmERIA&query=hidenavigation%3D1%26view%3Dpreview" style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;\\" sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"></iframe>

Note: If you are using gatsby-remark-responsive-iframe, it must appear after this plugin in your configuration or the iframe will not be transformed.

Package.json file

CodeSandbox requires a package.json file in order to work. This is useful because you can define dependencies such as react that will be included in the sandbox.

The plugin will search for the package.json file in the example folder. If not found, it will try in the parent folders up until it reaches the examples root folder.

If nothing is found it fall back to a default one:

{
  "name": "example",
  "dependencies": {}
}

Overriding options on single sandboxes

It's possible to override the global embedding options on a per-sandbox basis, by simply passing them as url query in the generating link.

[hello world example](embedded-codesandbox://hello-world-example?view=split)

The options will be merged with the global one.

How does it work?

CodeSandbox uses the same URL compression schema used by the Babel REPL to embed the local code example in a URL.

This is than passed to the (awesome) define api to generate a sandbox on the fly.

Installation

yarn add gatsby-remark-embedded-codesandbox

Usage

// In your gatsby-config.js
{
  resolve: 'gatsby-transformer-remark',
  options: {
    plugins: [
      {
        resolve: 'gatsby-remark-embedded-codesandbox',
        options: {
          // Required:

          // Example code folders are relative to this dir.
          // eg src/_examples/some-example-folder
          directory: `${__dirname}/src/_examples/`,

          // Optional:

          // Custom protocol for parsing the embedding link
          // default:
          protocol: 'embedded-codesandbox://',

          // Customise CodeSandbox embedding options:
          // https://codesandbox.io/docs/embedding#embed-options
          // default:
          embedOptions: {
            view: 'preview',
            hidenavigation: 1,
          },

          // Customise the embedding iframe given the generated url
          // default:
          getIframe: url => `<iframe src="${url}" class="embedded-codesandbox" sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"></iframe>`
        }
      }
    ]
  }
}

gatsby-remark-embedded-codesandbox's People

Contributors

elboman avatar karlhorky avatar lekoarts avatar undistraction avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

gatsby-remark-embedded-codesandbox's Issues

Make options configurable per embed

Allow configuration of settings on a per-embed basis (maybe as a query string or something after the path to the examples folder?)

For example, module is a very nice option to have:

Which module to open by default. Multiple paths comma separated are allowed, in that case we show them as tabs.

Workaround: Add multiple Remark plugin configuration blocks with different protocols (eg. embedded-html-sandbox:// for configuration for html files, embedded-react-sandbox:// for React configuration)

Feature: Support large sandbox content

If the content passed to the GET define API is too large, CodeSandbox will return an HTTP 414 error (URI Too Long).

fetching the POST define API with ?json=1 (the "Define without Render" option) and then using the resulting URL for the iframe would be a workable solution:

https://codesandbox.io/docs/importing#xhr-request

This would require running asynchronous code within the transformer function, which can be achieved by returning a promise:

https://github.com/swimlane/DocSPA/blob/9155c2e07fa3105f4e7858e62e9877cfc4105706/projects/swimlane/docspa-remark-preset/src/plugins/short-codes.ts#L106

More information about async remark plugins: gatsbyjs/gatsby#16403

Resolution of package.json and default package.json

Would be great if the plugin used a simple resolution algorithm to resolve the package.json for the example. It should look in the example's directory, then in the root code directory, then fall-back to the simplest possible config (as outlined in the README):

{
  "name": "example",
  "dependencies": {}
}

This would:

  • make sure the plugin worked out of the box
  • allow a single shared package.json to be shared amongst multiple examples

Allow for custom package.json path in config

The default resolution of package.json is good. However I don't want to use the first package.json it finds by walking up the tree OR specifying a new package.json in each example.

We have a repo which includes application code & docs code. I essentially want to reference the root package.json for the application code rather than the docs package.json with all the gatsby deps.

This will allow packages to stay in sync with docs.

Feature: Allow customization of more URL parts (or full URL?)

At the moment, some parts of the url such as embed are hard coded:

const sandboxUrl = `https://codesandbox.io/api/v1/sandboxes/define?embed=1&parameters=${params}&query=${encodedEmbedOptions}`;

It would be nice if this was more customizable. I could imagine either:

  1. An option for each different possible parameter
  2. A getUrl or similar function to override the URL completely

Use Case

I am including links in the page instead of embedded sandboxes, and want to link to the full sandbox page.

Workaround

Manually .replace the necessary parts of the URL in getIframe:

options: {
  // ...
  // Remove all embed options because we're not currently using embeds
  embedOptions: {},
  // Customize the output of the plugin:
  // - Use a link instead of an iFrame
  // - Link to the full Sandbox URL instead of the embed version
  getIframe: url =>
    `<a
       href="${url.replace('embed=1&','',)}"
       target="_blank"
       rel="nofollow,noopener,noreferrer"
     >CodeSandbox</a>`,
},

I'm only getting a black box for embed

I'm using this with gatsby-mdx plugins and the embed is a black box.

My plugin usage:

          {
            resolve: 'gatsby-remark-embedded-codesandbox',
            options: {
              // Required:
    
              // Example code folders are relative to this dir.
              // eg src/_examples/some-example-folder
              directory: `${__dirname}/src/examples/`,
    
              // Optional:
    
              // Custom protocol for parsing the embedding link
              // default:
              protocol: 'embedded-codesandbox://',
    
              // Customise Codesandbox embedding options:
              // https://codesandbox.io/docs/embedding#embed-options
              // default:
              embedOptions: {
                view: 'editor',
                hidenavigation: 1,
              },
    
              // Customise the embedding iframe given the generated url
              // default:
              getIframe: url => `<iframe src="${url}" class="embedded-codesandbox" sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"></iframe>`
            }
          },

Here's the link that get's generated:

https://codesandbox.io/api/v1/sandboxes/define?embed=1&parameters=N4IgZglgNgpgziAXKCA7AJjAHgOgFYLIgDGA9qgC4yVIjYAOpAThQASZgCGArlGwBQBKVgF4AfKwA6IABIwoUUqwDqzKOmkBuEAF8ANCHqdiAa04BzGPjjkkoMpWoU7IALac0tNJlwFdOgKA&query=hidenavigation%3D1%26view%3Deditor

Files in example directories being cached

Reproduction steps:

  1. Create a link to an example directory (CodeSandbox A generated)
  2. Change a file in that example directory (CodeSandbox A remains)
  3. Restart the server
  4. CodeSandbox A still remains
  5. Clear the Gatsby cache with gatsby clean and restart the server
  6. CodeSandbox B generated (from change in 2. above)

Fast solution: I suppose the simplest way of dealing with this for now would be to document the fact that files are cached and that you should clear your Gatsby cache every time you make a change.

Good solution: Clean the cache of example directories on every server restart.

Typo in the Readme on NPM

In the Usage section you provide the code to configure the plugin inside the gatsby-config.js file.

If someone copy/pastes this config like I did they will receive an error when they run their Gatsby app.

Gatsby is spelled incorrectly in the resolve key.

resolve: 'gastby-remark-embedded-codesandbox',

should be

resolve: 'gatsby-remark-embedded-codesandbox',

This has been fixed on the Readme in the Repo but NOT on npm and therefor not on the Gatsby website either.

v2?

Does this work with v2 of Gatsby? Doesn't seem to, but not sure if I was doing something wrong. 😸

Error: Unable to find plugin "gastby-remark-embedded-codesandbox". Perhaps you need to install its package?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.