My Developer Account

Add-ons API Reference

Your add-on JavaScript executes in a DedicatedWorkerGlobalScope, and thus you don't have access to document, window, or any other objects available in a normal browser context.

You do have access to these three global functions, plus the renderExtension entry point:

authenticatedFetch

This function is similar to the browser's fetch function, but it automatically adds the necessary Authorization header to make requests to the Planning Center API on behalf of the user.

const response = await authenticatedFetch(
  'https://api.planningcenteronline.com/people/v2/me'
);
const data = await response.json();
console.log(data);

The function returns a Promise that resolves to a Response object, just like the standard fetch API.

authenticatedIntegratorFetch

This function is similar to authenticatedFetch, but it makes requests to your (the Integrator's) API instead of the Planning Center API. It automatically adds the necessary Authorization header using the token obtained from your OAuth Server.

const response = await authenticatedIntegratorFetch(
  'https://your-api.example.com/send-message',
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      message: 'Hello, World!',
      recipients: [1, 2, 3]
    })
  }
);
const data = await response.json();
console.log(data);

Like authenticatedFetch, this function returns a Promise that resolves to a Response object.

addOnEnvironment

This function returns a string indicating which environment your add-on is currently running in. This is useful for conditional logic or debugging.

const env = addOnEnvironment();
console.log(env); // "testing", "beta", or "production"

if (env === 'testing') {
  console.log('Running in testing mode');
}

Possible return values:

  • "testing" - Your add-on is in testing mode and only visible to your organization
  • "beta" - Your add-on is in beta and available to organizations that have opted in
  • "production" - Your add-on is publicly available to all Planning Center organizations

renderExtension

This is the main entry point for your add-on. Import it from @planningcenter/add-ons/integrator and pass it your root React component. Planning Center renders that component and passes it the insertion point's args as props.

import React from "react"
import { Button, Text, renderExtension } from "@planningcenter/add-ons/integrator"

function App({ location, closeModal, currentPersonId, currentOrganizationId }) {
  return (
    <>
      <Text>Hello from {location?.host}!</Text>
      <Button onClick={() => closeModal()} text="Close" />
    </>
  )
}

renderExtension(App)

Props passed to your component

  • location - An object describing where your add-on is being rendered, with host, pathname, and protocol properties (see Insertion Points for the insertion point identifier itself)
  • currentPersonId - The ID of the currently logged-in user
  • currentOrganizationId - The ID of the current organization
  • Additional properties specific to each insertion point (see Insertion Points for details)

Upgrading? Add-ons written against @remote-ui used a global onRender callback instead. That is supported until 2027-01-01 - see Upgrading from @remote-ui to @remote-dom.