Farther ShoreDocs
Go to Farther Shore
Frontend SDK
Start with the managed frontendZero-config clientRequest boundariesGit-triggered hostingRoll backReact hooks
Root & data components
Auth & sessions
Access-aware UI
Permission gates
Custom components
Variables
@farthershore/farthershore-js
Share with another member
Shared and private in one portal
@farthershore/farthershore-js exports
@farthershore/farthershore-js/react exports
@farthershore/farthershore-js/test-utils exports
@farthershore/farthershore-js/errors exports
@farthershore/farthershore-js/components exports
@farthershore/farthershore-js/components/docs-chrome exports
frontend-sdk HTTP contracts
Status
Docs/Build the customer UI/Frontend SDK

Frontend SDK

Build a managed subscriber portal, understand runtime configuration, and follow the Git-triggered release flow.

@farthershore/farthershore-js connects a browser UI to Farther Shore platform state and to the business routes behind the gateway. The frontend never needs a backend origin, Core URL, business id, environment id, or auth endpoint in its source code when it is hosted by Farther Shore.

The business contract lives in business/; editable UI code lives in frontend/. Plans, routes, meters, and permissions are repository contract state. Navigation, page composition, CSS, and browser interactions belong to the frontend application.

Start with the managed frontend

The managed repository intentionally starts without sample frontend source. The platform's standard subscriber experience remains available until you add a custom frontend/ application. A custom hosted frontend is an opt-in part of the managed repository; create that project, install @farthershore/farthershore-js, and keep its package and Vite configuration under frontend/.

The local commands below require that frontend/package.json already exists:

bash
pnpm --dir frontend install
farthershore frontend dev

frontend dev starts Vite with hot reload. With no live configuration it uses deterministic mock data and bypassed auth for local page work. To serve a production build locally:

bash
farthershore frontend preview

Opt into real platform data with --live, --core-url, or VITE_FS_CORE_URL. The CLI injects a temporary window.__FS_CONFIG__ shim; it does not edit your Vite config or frontend source.

Zero-config client

Hosted HTML receives an environment-specific window.__FS_CONFIG__ from the edge. The SDK reads it lazily, so client creation is safe at module scope:

tsx
import { createFartherShoreClient } from "@farthershore/farthershore-js";
import { FartherShoreRoot } from "@farthershore/farthershore-js/components";

const fs = createFartherShoreClient();

export function App() {
  return (
    <FartherShoreRoot client={fs}>
      <Portal />
    </FartherShoreRoot>
  );
}

The public client factory accepts application concerns such as organization selection, mock mode, retry behavior, injected fetch, and error callbacks. Platform routing and authentication are intentionally not part of custom hosted frontend configuration; the platform supplies them.

FartherShoreRoot mounts the client provider, bootstrap gate, managed auth, customer-readiness and legal gates, error boundary, and environment badge. A signed-in customer does not reach application children until the selected organization has an ACTIVE subscription with a non-null compiled plan. When that entitlement is missing, the root presents the managed organization picker and plan onboarding flow, then refetches the subscriber record before mounting the application. A catalog entry alone is never treated as enrollment.

The root also includes the managed legal Markdown renderer and its GFM runtime dependencies. A frontend using the root must not install react-markdown or remark-gfm separately. The SDK ships no CSS; the frontend repository owns presentation.

Request boundaries

SDK surfaceDestinationCredential
fs.bootstrap() and public business resolutionFarther Shore platformnone
keys, usage, billing, plans, account and team resourcesFarther Shore platformsubscriber session
fs.route.get/post/…business gateway routeSDK-managed signed browser context
fs.integration(id)compiled same-origin integration gatewaysigned-in subscriber session

The platform injects environment routing and the SDK attaches its managed browser context. Your code does not concatenate an environment hostname, select a backend origin, receive a bearer, or supply an access key. A route call is still enforced against the subscriber's current plan, permission, subject type, subscription state, and limits at request time.

ts
const jobs = await fs.route.get("/v1/jobs");

Use typed errors and stable denial codes for UI remediation; never treat a hidden button as authorization.

Git-triggered hosting

Hosted frontend releases follow repository events. There is no separate manual deployment trigger.

ScopeBuild triggerActivation
ProductionPublish a GitHub Release from the managed repositorySuccessful release build becomes the production frontend according to release policy
Preview environmentPush to that environment branchSuccessful build becomes the frontend for that environment
Localfarthershore frontend dev or frontend previewLocal Vite process only

After a push or GitHub Release, inspect the latest known build for that exact source revision:

bash
farthershore frontend status my-business \
  --ref "$(git rev-parse HEAD)" \
  --wait

For a preview environment:

bash
farthershore frontend status my-business \
  --env <environment-name-or-id> \
  --ref "$(git rev-parse HEAD)" \
  --wait \
  --timeout 900

status reports the current release plus recent builds and failure reasons. --ref limits the observation to the latest known build for that immutable source revision; it does not identify a particular webhook delivery. Exact attempt proof requires the build id returned by an enqueue response when one is available. --wait exits nonzero if the observed build fails or the timeout elapses.

A change to an FS_PUBLIC_ Variable also enqueues a frontend rebuild because its value is baked into the bundle. A write-only secret does not rebuild the frontend — it never enters the bundle; it is published to the edge for a named integration that references it.

Roll back

Find a previously successful release id in frontend status, then reactivate it:

bash
farthershore frontend rollback my-business --release-id <release-id>

For production, omitting --env changes the active hosted artifact and pins the production target. A later Release can build the repository fix, but the successful build does not autoactivate while the pin remains. After proving the new release id is healthy, explicitly reactivate it with the same frontend rollback command and read status back. There is no separate unpin command.

For a preview environment, add --env <environment-id>. Preview rollback changes the active artifact but does not pin it: the next successful build for that environment autoactivates. Treat preview rollback as temporary containment, stop or fix the source that is producing bad builds, and verify the active release again after every preview build.

React hooks

For custom presentation, mount FartherShoreProvider directly or use it through FartherShoreRoot. Hooks follow the common shape { data, error, isLoading, isError, isSuccess, refetch, queryKey } and add domain mutations:

tsx
import { useApiKeys, useUsage } from "@farthershore/farthershore-js/react";

function Usage() {
  const usage = useUsage();
  if (usage.isLoading) return <p>Loading…</p>;
  if (usage.error) return <p>Usage unavailable.</p>;
  return <pre>{JSON.stringify(usage.data, null, 2)}</pre>;
}

See Root and data components, Auth and sessions, and Variables for the three integration boundaries most custom portals need.

NextRoot & data components

On this page

Start with the managed frontendZero-config clientRequest boundariesGit-triggered hostingRoll backReact hooks