Primitree

Live API Hooks

Enterprise Figma Variables REST API hooks with SWR caching.

Figma limits the Variables REST API to Enterprise organizations. Reads need file_variables:read and access to the file. Mutations need a Full seat or administrator role, edit access, and file_variables:write.

Page scripts in that browser session can read the personal access token you pass to FigmaVariablesProvider. Use the live hooks in an access-controlled internal tool. Keep the token out of source control and public browser bundles. Public applications can call the @primitree/core request helpers from server code.

Provider

import {
  FigmaVariablesProvider,
  useInvalidateVariables,
  useVariables,
  useUpdateVariable,
} from '@primitree/hooks'

interface InternalVariablesAppProps {
  token: string
  fileKey: string
}

function InternalVariablesApp({ token, fileKey }: InternalVariablesAppProps) {
  return (
    <FigmaVariablesProvider
      token={token}
      fileKey={fileKey}>
      <VariablesDashboard />
    </FigmaVariablesProvider>
  )
}

function VariablesDashboard() {
  const { data, error } = useVariables()
  const { mutate: update, isLoading: saving } = useUpdateVariable()
  const { invalidate } = useInvalidateVariables()

  const renameVariable = async () => {
    const result = await update({
      variableId: 'VariableID:123:456',
      payload: { name: 'color/bg/brand' },
    })

    if (result) {
      invalidate()
    }
  }

  if (error) return <p role='alert'>{error.message}</p>

  return (
    <button
      disabled={saving || !data}
      onClick={renameVariable}>
      Rename variable
    </button>
  )
}

Query hooks

  • useVariables, usePublishedVariables
  • useVariableCollections, useVariableModes
  • useVariableById, useCollectionById, useModesByCollection

Mutation hooks

Each mutation hook returns { mutate, data, error, isLoading, isSuccess, isError }:

  • useCreateVariable
  • useUpdateVariable
  • useDeleteVariable
  • useBulkUpdateVariables

useInvalidateVariables() returns invalidate and revalidate. Call one after mutate returns a result.

Offline fallback

Pass a local variables response instead of a token and file key:

<FigmaVariablesProvider token={null} fileKey={null} fallbackFile={variablesJson}>

useVariables and the local collection queries read local response data. usePublishedVariables needs a published variables response. Set fallbackKind='local' or fallbackKind='published' when empty maps prevent the provider from identifying the response type.

Errors and retries

import {
  fetcher,
  getRetryAfter,
  isFigmaApiError,
  isRateLimited,
  withRetry,
} from '@primitree/core'

async function loadVariablesOnServer(url: string, token: string) {
  const fetchWithRetry = withRetry(() => fetcher(url, token), {
    maxRetries: 3,
    retryOnlyRateLimits: true,
  })

  try {
    return await fetchWithRetry()
  } catch (error) {
    if (isRateLimited(error)) {
      console.error('Retry after seconds:', getRetryAfter(error))
    } else if (isFigmaApiError(error)) {
      console.error('Figma API status:', error.statusCode)
    }
    throw error
  }
}

SWR config

<FigmaVariablesProvider
  token={token}
  fileKey={key}
  swrConfig={{ refreshInterval: 30_000 }}>