No build step? One classic script tag installs OakData on static sites, server-rendered templates, or any plain HTML page. The loader reads your key from the tag and boots the SDK from a CDN.
In a hurry? Paste this prompt into Claude Code, Cursor, or any agent working on your site, and give it your public key when asked:
Add OakData product analytics to this site (no build step).
- 1
In the shared layout - or every page's <head> - add:
<script defer data-key="<my public key, starts with oak_pub_>" src="https://oakdata.co/js/script.js"></script>Ask me for the key value if you don't already have it.
- 2
If the site has a login flow, call oak.identify(user.id, { email: user.email }) when it resolves, and oak.reset() on logout. window.oak is available as soon as the tag is parsed - early calls are queued.
- 3
For important buttons and links, prefer declarative tracking: add data-oak-event="event_name" plus data-oak-prop-* attributes instead of inline JS handlers.
Don't add any other analytics providers. Show me the changes before applying them.
Drop-in snippet
Paste this near the end of your <head> (or before </body>), with your project's public key (oak_pub_…):
<script
defer
data-key="oak_pub_xxxxxxxxxxxxxxxxxxxxxxxx"
src="https://oakdata.co/js/script.js"></script>That one tag boots the tracker: pageviews fire on load, and autocapture records clicks and form submits. It also assigns window.oak, so any inline script or handler can call the API. The ingest host follows the domain in src - which is what makes the managed reverse proxy a one-word change.
Calls before the SDK loads are safe
From the moment the tag is parsed, oak.* calls are queued and replayed once the SDK is up - inline handlers never have to worry about load order.
Tracking events & identifying users
<button onclick="oak.capture('cta_clicked', { location: 'hero' })">
Get started
</button>
<script>
// After your own login flow resolves:
oak.identify('user_123', { email: 'sam@example.com' })
</script>Public keys only
Page source is public - only ever put a oak_pub_… key in a script tag. Secret keys (oak_sec_…) are for the REST API and MCP server, and must stay server-side.
Prefer an ES module?
The loader is a convenience wrapper - the SDK itself is a standard ES module on npm, so you can import it directly from a CDN and call init yourself. Pinning the version (@1) stops the CDN from silently crossing a breaking change.
<script type="module">
import oak from 'https://esm.sh/oakdata-js@1'
oak.init('oak_pub_xxxxxxxxxxxxxxxxxxxxxxxx', {
api_host: 'https://oakdata.co',
})
// Expose globally so inline handlers can call oak.* anywhere on the page.
window.oak = oak
</script>Ad-blockers eating your data?
Filter lists block requests to analytics domains. Serve OakData first-party from a subdomain of your own site with one CNAME record - see the managed reverse proxy.
The SDK reference covers every method and init option.