Skip to main content

Custom Content

The Sandpack component you used in the previous section is called a preset. It wraps all the individual components and provides sensible defaults.

Presets make it easy to adopt sandpack, while offering extensive configurability. The first thing we will look at is how to configure the content that runs inside sandpack.

Templates

By default your Sandpack instance starts with a predefined template. Each template contains all the files and dependencies needed to start a project. For instance, the vue template will contain the starter files generated by the vue-cli, and the react template those generated by create-react-app.

import { Sandpack } from "@codesandbox/sandpack-react";
import "@codesandbox/sandpack-react/dist/index.css";

export default function App() {
  return (
    <Sandpack 
    // Try out the included templates below!
    template="react"
    // template="react-ts"
    // template="angular"
    // template="vue"
    // template="vue3"
    // template="vanilla-ts"
    // template="vanilla" // default
    />
  );
}

The template prop accepts a string, and has a variety of presets. The complete list of included templates might change over time, so check the API reference for the supported templates. If the template prop is not passed or has an invalid value, it defaults to vanilla.

Custom File Contents

Once you've chosen your starter template, you will most likely want to pass custom code into your Sandpack instance. The simplest way to do this, is to add and override files via the files prop.

import { Sandpack } from "@codesandbox/sandpack-react";
import "@codesandbox/sandpack-react/dist/index.css";

const code = `export default function App() {
  return <h1>Hello Sandpack</h1>
}`;

export default function App() {
  return (
    <Sandpack 
      template="react"
      files={{
        "/App.js": code,
      }}
    />
  );
}

The files prop accepts an object, where each key is the relative path of that file in the sandbox folder structure. Files passed in through the files prop override those in the template structure. Since each template uses the same type to define the files, you can overwrite the contents of any of the template files.

Keep in mind that the tabs only show the name of the file and not the full path. For instance, if you want to overwrite /index.js in the vanilla template, you need to specify /src/index.js as the corresponding key in the files object. You can check the full paths for each of the templates in the template definitions.

Leading Slash

Don't forget the leading slash (/) when setting the file paths.

Available Files

Notice that when passing the files prop, only the content you pass there is available in the file tabs. The other files in the template are still bundled together, but you don't see them anymore.

Dependencies

Any template will include the needed dependencies, but you can specify any additional dependencies.

NPM Dependencies

Inside customSetup prop you can pass a dependencies object. The key should be the name of the package, while the value is the version, in exactly the same format as it would be inside package.json.

<Sandpack
  template="react"
  files={{
    "/App.js": `...`,
  }}
  customSetup={{
    dependencies: {
      react: "17.0.2",
      "react-dom": "17.0.2",
      "react-scripts": "4.0.0",
    },
  }}
/>

Static External Resources

You can also pass an array of externalResources into the options prop to specify static links to external CSS or JS resources elsewhere on the web. These resources get injected into the head of your HTML and are then globally available.

<Sandpack
  options={{
    externalResources: [
      "https://unpkg.com/@tailwindcss/ui/dist/tailwind-ui.min.css",
    ],
  }}
  template="react"
/>

Advanced Usage

Hidden Files

Sometimes you might want to pass some custom code to Sandpack, but you don't want the users to see that code. For example, you might have some stylesheet that should not be editable but helps you in your examples.

Instead of passing a string as the value of each file in the files prop, you can pass an object. With this format the content is passed as the code property and you can pass additional flags to customize the sandpack experience. For example, you can pass a hidden flag for files that you don't want to show to the user:

<Sandpack
  files={{
    "/App.js": `...`,
    "/button.js": `...`,
    "/link.js": {
      code: `...`,
      hidden: true,
    },
  }}
  template="react"
/>

The hidden flag is false by default.

info

You can use the object notation only for the files which need additional flags, while the other files can be passed as a string.

Active File

You can also specify the active file, which is open in the code editor when the component mounts. If no active flag is set, the first file will be active by default:

<Sandpack
  files={{
    "/App.js": reactCode,
    "/button.js": {
      code: buttonCode,
      active: true,
    },
    "/link.js": {
      code: linkCode,
      hidden: true,
    },
  }}
  template="react"
/>
info

The active flag has precendence over the hidden flag. So a file with both hidden and active set as true will be visible.

Read-only mode

You can set one, multiple files, or the entire Sandpack as read-only, which will make all files non-editable.

Per file:

<Sandpack
  files={{
    "/App.js": reactCode,
    "/button.js": {
      code: buttonCode,
      readOnly: true,
    },
  }}
  template="react"
/>

Globally:

<Sandpack
  options={{
    readOnly: true,
  }}
/>

Plus, you can hide the Read-only label which appears on top of the code editor:

<Sandpack
  options={{
    readOnly: true,
    showReadOnly: false,
  }}
/>

openPaths and activePath

You can override the entire hidden/active system with two settings (openPaths and activePath) inside the options prop.

Notice that both options require you to match the exact file paths inside the sandbox, so use with caution as this can quite easily create errors in the long term.

<Sandpack
  template="react"
  files={{
    "/App.js": reactButtonCode,
    "/button.js": buttonCode,
  }}
  options={{
    openPaths: ["/App.js", "/button.js", "/index.js"],
    activePath: "/index.js",
  }}
/>
info

When openPaths or activePath are set, the hidden and active flags on the files prop are ignored.

Custom Entry File

Additionally, you can also specify a different entry file for the sandbox. The entry file is the starting point of the bundle process.

<Sandpack
  template="react"
  files={{
    "/App.js": `...`,
  }}
  customSetup={{
    entry: "/index.js",
  }}
/>
warning

If you change the path of the entry file, make sure you control all the files that go into the bundle process, as prexisting settings in the template might not work anymore.

Fully Custom Setup

Sometimes you might not want to start from any of the preset templates. If so, you can pass a full customSetup object that contains everything needed for your custom Sandpack configuration.

Most individual parts of the customSetup have been described above, but for a full overview of what is accepted in a custom setup, check out the type definitions.