import { CodeBlock } from "../../components/CodeBlock";
import Templates from "../../components/Templates";
import { Callout } from "nextra-theme-docs";

# Usage

<br/>
<img src="/docs/frameworks.jpg" />

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`.

<Templates />

The `template` property accepts a [defined preset list](https://github.com/codesandbox/sandpack/blob/main/sandpack-client/src/types.ts#L384). If the property is not passed, `vanilla` will be set by default.

## Files

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.

<CodeBlock stack>
{`import { Sandpack } from "@codesandbox/sandpack-react";

export default function App() {
  return (
    <Sandpack 
      template="react"
      files={{
        "/App.js": \`export default function App() {
  return <h1>Hello Sandpack</h1>
}\`,
      }}
    />
  );
}
`}
</CodeBlock>

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](https://github.com/codesandbox/sandpack/tree/main/sandpack-react/src/templates).

<Callout type="info">
  **Available Files**<br />
  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.
</Callout>

### File format

The files prop accepts two formats of object, `string` or another `object`, where you can pass other configurations for the file. 

<CodeBlock stack>
{`import { Sandpack } from "@codesandbox/sandpack-react";

export default function App() {
  return (
    <Sandpack
      files={{
        '/Wrapper.js': \`export default () => "";\`,
      
        '/Button.js': {
          code: \`export default () => {
  return <button>Hello</button>
};\`,
          readOnly: true, // Set as non-editable, defaults to \`false\`
          active: true, // Set as main file, defaults to \`false\`
          hidden: false // Tab visibility, defaults to \`false\`
        }
      }}
      template="react"
    />
  )
};
`}
</CodeBlock>

If no active flag is set, the first file will be active by default:

<Callout type="info">
  The `active` flag has precendence over the `hidden` flag. So a file with both
  `hidden` and `active` set as `true` will be visible.
</Callout>

## 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`.

<CodeBlock stack>
{`import { Sandpack } from "@codesandbox/sandpack-react";

export default function App() {
  return (
    <Sandpack
      template="react"
      customSetup={{ 
        dependencies: { 
          "react-markdown": "latest" 
        }
      }}
      files={{
        "/App.js": \`import ReactMarkdown from 'react-markdown' 

export default function App() {
  return (
    <ReactMarkdown>
      # Hello, *world*!
    </ReactMarkdown>
  )
}\`
      }}
    />
  )
};`}
</CodeBlock>


### 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. Here's an example using the Tailwind CSS CDN:

<CodeBlock stack>
{`import { Sandpack } from "@codesandbox/sandpack-react";

export default function App() {
  return (
    <Sandpack
      template="react"
      options={{
        externalResources: ["https://cdn.tailwindcss.com"]
      }}
      files={{
        "/App.js": \`export default function Example() {
  return (
    <div className="bg-gray-50">
      <div className="mx-auto max-w-7xl py-12 px-4 sm:px-6 lg:flex lg:items-center lg:justify-between lg:py-16 lg:px-8">
        <h2 className="text-3xl font-bold tracking-tight text-gray-900 sm:text-4xl">
          <span className="block">Ready to dive in?</span>
          <span className="block text-indigo-600">Start your free trial today.</span>
        </h2>
        <div className="mt-8 flex lg:mt-0 lg:flex-shrink-0">
          <div className="inline-flex rounded-md shadow">
            <a
              href="#"
              className="inline-flex items-center justify-center rounded-md border border-transparent bg-indigo-600 px-5 py-3 text-base font-medium text-white hover:bg-indigo-700"
            >
              Get started
            </a>
          </div>
          <div className="ml-3 inline-flex rounded-md shadow">
            <a
              href="#"
              className="inline-flex items-center justify-center rounded-md border border-transparent bg-white px-5 py-3 text-base font-medium text-indigo-600 hover:bg-indigo-50"
            >
              Learn more
            </a>
          </div>
        </div>
      </div>
    </div>
  )
}\`
      }}
    />
  );
}`}
</CodeBlock>

## Advanced Usage

### 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:**

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

**Globally:**

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

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

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

### visibleFiles and activeFile

You can override the entire hidden/active system with two settings (`visibleFiles` and `activeFile`) 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.

<CodeBlock stack>
{`import { Sandpack } from "@codesandbox/sandpack-react";

export default () => {
  return (
    <Sandpack
      template="react"
      files={{ "/button.js": \`export default () => <button />\` }}
      options={{
        visibleFiles: ["/App.js", "/button.js", "/index.js"],
        activeFile: "/button.js",
      }}
    />
  )
}
`}
</CodeBlock>

<Callout type="info">
  When `visibleFiles` or `activeFile` are set, the `hidden` and `active` flags
  on the `files` prop are ignored.
</Callout>

### 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.

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

<Callout type="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.
</Callout>

### 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.
