Getting Deeper
If you open a preset file from the sandpack repository, you'll see it is made up of smaller sandpack components and has limited logic for passing props to those smaller components.
If you need a custom version of sandpack, you can opt in to use these smaller components, which are also exported from the main package.
Before talking about the actual components, let's dive into how sandpack manages its internal state.
Sandpack Provider
The core of sandpack is managed by the SandpackProvider
, central point of our
architecture. The provider abstracts the functionality of sandpack
and places
the public state values and functions on a context
object. The React
components that are exported by the main package (eg: SandpackCodeEditor
,
SandpackPreview
) use that context
object to communicate with sandpack
.
info
The SandpackProvider
accepts the same two props for getting input as the Sandpack
preset:
template
and customSetup
.
SandpackProvider
as well as the other sandpack components are named exports in the sandpack-react
package.
import { SandpackProvider, SandpackPreview } from "@codesandbox/sandpack-react";
const CustomSandpack = () => (
<SandpackProvider>
<SandpackPreview />
</SandpackProvider>
);
Running this snippet will render a preview with a vanilla template, because the sandpack logic is running behind
the scenes and the template, if omitted, is vanilla
.
However, you will notice that the buttons on the Preview look off. This is
because there is no styling applied to the sandpack components. For styling and theming, you need the SandpackThemeProvider
.
Clients
Under one Sandpack provider, you can have multiple sandpack-clients
. For example, the most common case for multiple clients is when more than one SandpackPreview has been rendered.
To access all the clients or to pass messages to the iframes under the same provider, use the useSandpack
hook, which gives a way to interact with these clients:
const ListenerIframeMessage = () => {
const { sandpack } = useSandpack();
const sender = () => {
Object.values(sandpack.clients).forEach((client) => {
client.iframe.contentWindow.postMessage("Hello World", "*");
});
};
return <button onClick={sender}>Send message</button>;
};
Theme Provider
The SandpackThemeProvider
is also exported from the main package. It needs to render inside the SandpackProvider
and it needs to surround any component that requires styling from sandpack.
import {
SandpackProvider,
SandpackThemeProvider,
SandpackPreview,
} from "@codesandbox/sandpack-react";
const CustomSandpack = () => (
<SandpackProvider>
<SandpackThemeProvider>
<SandpackPreview />
</SandpackThemeProvider>
</SandpackProvider>
);
Reminder
Don't forget to import the css stylesheet if you want to use the styling of the standard sandpack components.
The theme provider component will render a wrapper div around your sandpack components. The div scopes the theme variables and styling to this instance of sandpack, allowing you to style each instance independently.
Congrats!
You took the first step in understanding the internals of sandpack. In the next section you will go through the common sandpack components and will learn how to build your custom sandpack-aware component.