JavaScript
Add Specify to any JavaScript app.
Set up with the wizard
npx @specify-sh/wizard --publisherThe wizard runs through the coding agent you already use (Claude Code, Codex etc.). It inspects your codebase, proposes an integration plan and implements it as a reviewable diff.
Prefer to do it by hand? The manual steps below are the same setup.
Manual setup
Runnable example
vanilla-typescript is this guide as a working Vite app.
1. Install the SDK
npm i @specify-sh/publisher-sdk2. Initialize the client
You will need a publisher key. See Publisher keys.
Create the client once and import it wherever you serve an ad. Use the publisher key via your environment.
const specifyPublisherKey = 'spk_123...' // Bring this from your environment
export const specify = new Specify({
publisherKey: specifyPublisherKey
});3. Connect consent
If your site has a consent management platform, connect its targeted-advertising state to the SDK on every page load. The SDK does not persist consent.
import { specify } from './lib/specify';
// Adapt this code to your cookie consent management tool
specify.setCookieConsent(cmp.getConsent().targetedAdvertising);
cmp.onConsentChange((consent) => {
specify.setCookieConsent(consent.targetedAdvertising);
});With consent granted, Specify recognises returning visitors across every site in our network, so a placement can fill even when the user has not connected a wallet to your app.
4. Serve an ad
Choose the image format that matches your placement, and pass any wallet address the visitor controls.
Wrap the call so it can run more than once. A first serve often has neither consent nor a wallet to go on, and both usually arrive a moment later.
import { specify } from './lib/specify';
import { ImageFormat } from '@specify-sh/publisher-sdk';
let filled = false;
export async function serveAd(wallet) {
if (filled) return;
const ad = await specify.serve(wallet ?? null, {
imageFormat: ImageFormat.LANDSCAPE,
adUnitId: 'sidebar'
});
if (!ad) return;
filled = true;
render(ad);
}
specify.onIdentityChange(serveAd);
serveAd();onIdentityChange() runs when a wallet is registered or consent is granted, so a slot that came back empty tries again on its own. The filled flag keeps it to one ad: asking again over an ad already on the page would replace what the visitor is looking at.
Available image formats and the fields returned in the ad can be found in the Browser SDK reference.
Network requirements
The SDK sends ad requests to https://spfsrv.com. After consent, the browser sends these requests with credentials. If your site has a Content Security Policy, add https://spfsrv.com to connect-src.
Send SDK traffic straight to Specify. Do not proxy it through your backend because a proxy strips cookies and geolocation information.