Join us live: Rapid Frontend Prototyping with Cursor & Storybook

CodePen Launcher

Using CodePen's "POST to Prefill" feature, a button is created in the toolbar that allows you to launch your demo code into a codepen editor, complete with JS and CSS

View on Github

Storybook Addon CodePen Launcher

This package is still in beta. Please submit any issues HERE.

This Storybook addon allows you to launch CodePen examples directly from your Storybook stories. Follow the steps below to integrate and use this addon in your project.

Storybook Addon CodePen Launcher

CodePen Launched

Installation

First, install the addon via npm:

npm install --save-dev @rkever2/storybook-addon-codepen-launcher

Register Addon

Add the addon to your Storybook configuration. Edit your .storybook/main.js file to include the addon:

// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
import type { StorybookConfig } from '@storybook/your-framework';

const config: StorybookConfig = {
  // ...rest of config
  addons: [
    '@storybook/addon-essentials'
    '@rkever2/storybook-addon-codepen-launcher', // 👈 register the addon here
  ],
};

export default config;

Configuration

You can configure the codepen launcher addon globally and at the story level. See CodepenSettingsConfig.json

Below is a basic example using the most basic settings.

Global Settings

Set your settings globally in your src/preview.js file. Any settings, whether set here or not, can be overwritten at the story level (see Story Settings below);

// src/preview.js
const preview: Preview = {
  parameters: {
    codepenLauncher: {
      settings: {
        titlePrepend: "My Project Name",
        resultsIframeBodyDefaultPadding: "10px",
        removeCommentsFromHtml: true,
      },
      options: {
        css_external:
          "https://URL_TO_MY_FRAMEWORK_STYLES",
        js_external:
          "https://URL_LINK_TO_MY_FRAMEWORK_SCRIPTS",
      },
    }
  }
};

export default preview;

Story Settings

Although not neccessary, you can modify any of the codepenLauncher settings at a story level.

import React from "react";
import { MyComponent } from "./MyComponent";

export default {
    title: "MyComponent",
    component: MyComponent,
};

const Template = (args) => <MyComponent {...args} />;

export const Default = Template.bind({});
Default.args = {
    // component props...
    args: {
        // component args...
    },
    parameters: {
        codepenLauncher: {
            settings: {
                // basic addon settings...
            },
            post: {
                // codepen post settings...
            },
            options: {
                // codepen options...
            },
        },
    },
};

Settings Explained

All Available Settings

  codepenLauncher: {
    settings: { // basic addon settings
        titlePrepend: "My Project", // Your project name
        titlePrependSeperator: " - ", // The seperator for new codepen name (prepends the story name)
        resultsIframeBodyDefaultPadding: "10px", // add padding to codepen (if not, it will hug the edge unless you've added CSS for that)
        removeCommentsFromHtml: false, // remove comments from HTML (usefull for lit or angular auto generated)
        removeCommentsFromCss: false, // remove comments from CSS
        removeCommentsFromJs: false, // remove comments from JS
        formatHtml: true, // format the HTML
        formatCss: true, // format the CSS
        formatJs: true // format the JS
    },

    post: { // codepen post prefill settings (see https://blog.codepen.io/documentation/prefill/) - NOTE that you shouldn't need to change these unless codepen changes them (before I can update) or offers alternative links you want to use
        actionUrl: "https://codepen.io/pen/define", // url defined by codepen
        target: "_blank", // How to open the new codepen window
        inputName: "data" // input name defined by codepen
    },

    options: { // see https://blog.codepen.io/documentation/prefill/
        title: "", // codepen title (if empty will just use story name)
        description: "", // description
        private: false, // true || false - When the Pen is saved, it will save as Private if logged in user has that privledge, otherwise it will save as public
        parent: null, // If supplied, the Pen will save as a fork of this id. Note it's not the slug, but ID. ou can find the ID of a Pen with `window.CP.pen.id` in the browser console.
        tags: [], // an array of strings
        editors: "111", // Set which editors are open. In this example HTML open, CSS open, JS open
        layout: "left", // top | left | right
        html: "", // codepen HTML
        html_pre_processor: "none", // "none" || "slim" || "haml" || "markdown"
        css: "", // codepen CSS
        css_pre_processor: "none", // "none" || "less" || "scss" || "sass" || "stylus"
        css_starter: "normalize", // "normalize" || "reset" || "neither"
        css_prefix: "neither", // "autoprefixer" || "prefixfree" || "neither"
        js: "", // codepen JS
        js_pre_processor: "none", // "none" || "coffeescript" || "babel" || "livescript" || "typescript"
        html_classes: "", // classes to add to HTML
        head: "", // content to add to iframes <head />
        css_external: "", // semi-colon separate multiple external CSS files
        js_external: "" // semi-colon separate multiple external JS files
    }
}

Settings Requirements

As mentioned under "Global Settings", there is really only one neccessary, although not required, setting you'll want to make sure is defined, global.title. The others are neccessary based on your individual requirements either globally or at a story level.

Setting: options.html

The HTML that's sent over to codepen will be taken from the storybook story context.canvasElement UNLESS you have set a value to the options.html such as in the case where you would like to customize the HTML at the story level. Lit, angular, and other libs sometimes drop comments in the rendered HTML. You can easily remove that by setting global.removeCommentsFromHtml = true (in src/preview.js for example);

Setting: options.css

The CSS, if not defined, will just scrape the CSS in the story's rendered iframe. You can override that by setting a value to options.css. You can also add external css file (preview.ts/jsx) by setting options.css_external.

Settings: options.js

There is no magic that pulls in JS from the story (at least at this point) and if you want it, you need to add it into the option at the story or global level (preview.ts/jsx). For library level JS files, you should use options.external_js but make sure they are publically available for codepen to use.

Made by
  • rkever2
    rkever2
Work with
    Angular
    Ember
    HTML
    Preact
    React
    React native
    Svelte
    Vue
    Web Components
Tags