Get started with plain React

Overview

This covers integrating Plasmic into your existing React codebase.

Want to quickly generate a new codebase with Plasmic already integrated? Follow this guide instead!

Installation

Copy
npm install @plasmicapp/loader-react
# or yarn add @plasmicapp/loader-react

Initialization

Initialize Plasmic with the project ID and public API token. Define this in its own module to make it available globally.

src/plasmic-init.ts
Copy
import { initPlasmicLoader } from "@plasmicapp/loader-react";
export const PLASMIC = initPlasmicLoader({
projects: [
{
id: "PROJECTID", // ID of a project you are using
token: "APITOKEN" // API token for that project
}
],
// Fetches the latest revisions, whether or not they were unpublished!
// Disable for production to ensure you render only published changes.
preview: true,
})

To find your project’s public API token: open the project in Plasmic Studio, and click the Code toolbar button.

Render a single Plasmic page or component

Note: You can auto-load all Plasmic pages at the correct routes (recommended) rather than manually loading individual pages—see next section.

For client-rendered or single-page apps, we fetch components dynamically at runtime. (These are cached for the lifetime of the application.)

Add <PlasmicRootProvider/> somewhere close to the root of your app, then drop in a <PlasmicComponent/> anywhere to render the actual component.

For example:

src/MyComponent.tsx
Copy
import { PlasmicRootProvider, PlasmicComponent } from '@plasmicapp/loader-react';
import { PLASMIC } from './plasmic-init';
function MyComponent() {
return (
<PlasmicRootProvider loader={PLASMIC}>
<PlasmicComponent component="COMPONENTNAME" />
</PlasmicRootProvider>
);
}

Auto load all Plasmic pages

To automatically render all Plasmic-defined pages at the routes specified in Plasmic, create a catch-all route for your specific routing framework.

Here is an example for react-router:

src/AppRoot.tsx
Copy
import {
initPlasmicLoader,
PlasmicRootProvider,
PlasmicComponent,
ComponentRenderData
} from '@plasmicapp/loader-react';
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
import { useEffect, useState } from 'react';
import { PLASMIC } from './plasmic-init';
function AppRoot() {
return (
<PlasmicRootProvider loader={PLASMIC}>
<Router>
<Switch>
{/* Your other routes... */}
<Route component={CatchAllPage} />
</Switch>
</Router>
</PlasmicRootProvider>
);
}
// We try loading the Plasmic page for the current route.
// If it doesn't exist, then return "Not found."
export function CatchAllPage() {
const [loading, setLoading] = useState(true);
const [pageData, setPageData] = useState<ComponentRenderData | null>(null);
useEffect(() => {
async function load() {
const pageData = await PLASMIC.maybeFetchComponentData(location.pathname);
setPageData(pageData);
setLoading(false);
}
load();
}, []);
if (loading) {
return <div>Loading...</div>;
}
if (!pageData) {
return <div>Not found</div>;
}
// The page will already be cached from the `load` call above.
return <PlasmicComponent component={location.pathname} />;
}

Add custom code components

Let your Plasmic Studio users drag/drop and visually manipulate any React component! (Learn more.)

Step 1

Create a special hidden page at route /plasmic-host.

Assuming you are using react-router, add a route for the host page. For example:

src/App.tsx
Copy
import * as React from 'react';
// If you are using loader-react:
import { PlasmicCanvasHost } from '@plasmicapp/loader-react';
// Or if you are using codegen:
// import { PlasmicCanvasHost } from '@plasmicapp/host';
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
import { PLASMIC } from './plasmic-init';
export default function AppRoot() {
return (
<Router>
<Switch>
{/* Your other routes... */}
<Route path="/plasmic-host" render={() => <PlasmicCanvasHost />} />
</Switch>
</Router>
);
}

Add this snippet to the head of your public/index.html, before React loads (assuming you’re using something similar to create-react-app, which has a public/index.html):

Copy
<head>
<script>
!function(){const n=window,i="__REACT_DEVTOOLS_GLOBAL_HOOK__",o="__PlasmicPreambleVersion",t=function(){}
if(void 0!==n){if(n.parent!==n)try{n[i]=n.parent[i]}catch(e){}if(!n[i]){const r=new Map
n[i]={supportsFiber:!0,renderers:r,inject:function(n){r.set(r.size+1,n)},onCommitFiberRoot:t,onCommitFiberUnmount:t}}n[i][o]||(n[i][o]="1")}}()
</script>
</head>

Step 2

Start your app:

Copy
npm run start

And check that you see a confirmation message at http://localhost:3000/plasmic-host.

Step 3

Create a simple example React component:

src/components/HelloWorld.tsx
Copy
import React from 'react';
export interface HelloWorldProps {
children?: ReactNode;
className?: string;
verbose?: boolean;
}
export function HelloWorld({ children, className, verbose }: HelloWorldProps) {
return (
<div className={className} style={{ padding: '20px' }}>
<p>Hello there! {verbose && 'Really nice to meet you!'}</p>
<div>{children}</div>
</div>
);
}

Step 4

Add the following to your plasmic-init.ts to register it:

src/plasmic-init.ts
Copy
import { HelloWorld } from './components/HelloWorld';
// ...
const PLASMIC = initPlasmicLoader(/* ... */);
PLASMIC.registerComponent(HelloWorld, {
name: 'HelloWorld',
props: {
verbose: 'boolean',
children: 'slot'
}
});

Step 5

Open https://studio.plasmic.app, click the menu for the current project, select "Configure project," and set it to http://localhost:3000/plasmic-host.

configure project menu

Step 6

Re-open this project (or reload this tab) to see your component listed in the insert menu!

insert code component

Later, after you deploy the route to production, update the project to use your production host URL instead, such as https://my-app.com/plasmic-host. This way, other members of your team (who can’t access your localhost dev server) will be able to open and edit the project in Plasmic.

Learn more about code components.

There’s much more to explore!

For example:

Continue learning in the full docs.