Skip to main content
To embed Surfer in your CMS, contact [email protected]. The panel shows one Content Editor, the document Surfer builds around your target keywords, holding the guidelines and the Content Score (The guidelines panel). It finds that Content Editor through a permalink, and it identifies the viewer either through their own Surfer session or not at all. The browser requirements are under Availability.

Two ways to identify the writer

Leave anonymous unset and the panel uses the writer’s own Surfer session. Set anonymous: true and the panel shows one Content Editor to whoever opens the page, with no Surfer sign-in. In signed-in mode the panel signs in with the Surfer session in the writer’s browser. That session reaches the panel through third-party cookies or storage access (Sign in and cookies). When the permalink resolves to no Content Editor, the writer links or creates one from the dashboard (When nothing matches). In shared mode you pass anonymous: true and a permalink that already resolves, usually one read from the API (Connect to an existing Content Editor). The panel never reads the viewer’s Surfer session, even when the browser has one. Whoever opens the page sees that Content Editor’s guidelines and score. Nothing in the panel lets them pick another Content Editor, create one, disconnect it, or open its settings. The two modes side by side: A permalink is the string that ties a page in your CMS to one Content Editor. Surfer resolves it by its value alone. Every Content Editor has two permalinks, edit and comment. Either one opens the panel. Use a nonempty, stable string as the permalink: the page URL, a token-prefixed URL, a hash from the API, or a random identifier of your own. How the library sets one:
  • init uses the page’s own URL, without its fragment, when you give no permalink option.
  • init uses the permalink option when you give one.
  • init prefixes a sharing token, when given, to either value (Sharing tokens).
  • initWithOptions returns a handle whose setPermalink sends the value as you built it; the library adds nothing to it.
Surfer looks the value up as it arrives, with no account check. Anyone who has a permalink can open that Content Editor’s guidelines in a panel, signed in or not, so treat a permalink as a secret. The guidelines also need an active subscription on the organization that owns the Content Editor (Plans).
An edit permalink also opens the document for editing in the Surfer app, without a sign-in. A comment one opens it for viewing and commenting. A page URL that anyone can guess is a permalink that anyone can guess; prefix a sharing token before you rely on it.

Connect to an existing Content Editor

Read the Content Editor’s permalinks from the API and pass the hash as the permalink. This workflow needs API access, an API key, and the workspace and Content Editor IDs. Authentication covers who has access and how to get a key.
1

Pick or create the Content Editor

Create it through the API (Create Content Editor) or pick an existing one.
2

Wait for the Content Editor to complete

The permalink endpoints answer 409 until its state is completed.
3

List its permalinks

Call List Content Editor permalinks. Each item carries three fields:
  • type is edit or comment.
  • hash is the value the panel resolves.
  • url is the address of that permalink in the Surfer app, for people.
4

Pass the hash to the panel

A sharing token would be prefixed to the hash, and the result would resolve to nothing. Pass the hash as the permalink option of init, or to setPermalink, with no sharing token.
The panel opens with that Content Editor’s guidelines for whoever loads the page, in either mode. A reset gives the Content Editor new permalinks, and the old ones stop working (Revoke share links). A page still passing an old value gets the dashboard or the connect screen until you pass the new one. Update the page in the same change. v1 returns the edit permalink as permalink_hash on Get Content Editor query, with no url. It is the same value as the edit hash in v2.

Sharing tokens

When your page URLs are guessable, prefix a secret token to the permalink, unique per document and never changed. init takes the token as its second argument, joins it to the permalink with no separator, and URL-encodes the result. That encoded string is the permalink Surfer stores and resolves. init builds it the same way from the page URL it derives and from a permalink option. Add this to your editor page after the loader snippet from the quickstart, where token holds the token stored with the document:
For a page at https://your.cms.com/posts/42 and the token 7f0c2d1e, the permalink Surfer stores is the URL-encoded form of:
Three rules keep the token doing its job:
  • Generate it once per document, random and long enough not to be guessed. A UUID works. One token for the whole integration lets anyone who holds one permalink guess the others.
  • Store it with the document and pass the same value on every load.
  • Never change it. A changed token makes a different permalink, which resolves to nothing. The page then shows the dashboard or the connect screen, and the Content Editor stays linked to the old value until someone links it again.
initWithOptions has no token argument. Pass encodeURIComponent(token + url) to setPermalink (JavaScript API).

When nothing matches

A permalink that resolves to no Content Editor gets the dashboard for a signed-in writer and the connect screen for everyone else. The quickstart’s table under What you see shows what each state looks like. Creating a Content Editor from the dashboard spends one Content Editor credit (Credits). What follows for your page:
  • Linking a Content Editor from the dashboard sets its edit permalink to the page’s permalink, so the API lists that value from then on.
  • Linking replaces any page the Content Editor was linked to before.
  • In shared mode the connect screen leads nowhere, because the panel ignores any Surfer session. Pass a permalink that resolves.
The library reports the outcome to your page through onDraftLoaded, with null when nothing matched (JavaScript API).

White-label organizations

The permalink URLs the API returns use your organization’s white-label domain when one is set. The panel itself always loads from https://app.surferseo.com, whatever domain the organization uses, and is not white-labeled; that is Surfer’s policy for the embed. The hash is the same on a white-label organization, and the panel resolves it the same way. Which domain the url is built on is under Use cases.

Not offered

The embed shows and scores; it does not edit, write, or rebrand. The panel is never white-labeled (White-label organizations), and What stays in the Surfer app lists everything else the panel leaves to Surfer.