Getting started
Everything you need to integrate Hedgehog into your site or app.
Quick start
- Create your account — Sign up for free. When workspace creation is available to your account, create an organization and copy its ID from the dashboard.
- Add a widget — Drop the web component onto your page, or add the iOS or Android SDK to your app.
- Your readers sign in — The widget handles authentication for you. There are no tokens to manage.
Authentication is built in
No tokens to manage. Viewers sign in through the widget's own OAuth flow — on web, iOS, and Android. Pass a token only if you already manage member sessions yourself (SSO).
Embed on the web
Load a bundle from the Hedgehog CDN and drop in the custom element. It works in React, Vue, Angular, Svelte, or plain HTML — no framework integration required. Every widget takes your organization ID; the four content-scoped widgets also take a stable external content identifier (a slug or URL), the post feed takes a stable feed key and the post detail widget a post id, while notifications and profile are account-scoped. Viewers sign in through the widget. Load only the bundles you use, and replace <version> with an exact released SDK version. The web SDK release catalog identifies the current and available releases. A development or QA site that should always run the newest release can load https://assets.hedgehog.com/sdks/web/latest/ in place of a pinned version; production sites pin.
The comments widget opens on a Best tab — a curated feed the server selects and orders for you — alongside a Newest tab with the full discussion, newest first. Curation is server-side; there is nothing to configure.
Feed cards show an excerpt of the plain-text body with paragraph breaks, the first image, an attached video's poster, and reactions. Click the preview to read the full post; Read more appears only when text is truncated. Empty threads offer Start the conversation; active threads show a count beside Join the discussion. The discussion action opens the thread in the built-in detail view. Comments are only shown in detail; reactions are available in both views. Returning from built-in detail preserves your feed position. Custom host routing owns scrolling and return-state restoration on its destination page. Post bodies display Markdown literally; the composer has no text-formatting controls.
Posts may contain images or a video without a caption. Attach a moderation-approved image or an uploaded video; completely empty posts are not allowed. Images keep their full aspect ratio without cropping, bounded by the card width and a maximum height of 420 in the feed or 640 in detail (pixels on web, points on iOS, dp on Android). Select an image in detail to view it full-size. Videos are off by default. When video is available for your workspace, enable Allow post videos on the Moderation page. Playback-only mode keeps existing videos playable while stopping new uploads. Posts support one MP4, MOV, or WebM video up to 100 MB and two minutes. Upload progress, live encoding progress, retry, and playback are built in, and a post can be submitted while its video is still processing: it shows in the author's feed with progress and goes live once the video is ready. Post text and video are moderated before publication; audio is not checked.
A post feed opens a post's detail view in place by default, setting #hedgehog-post=<id> on the page URL so the view can be shared. The fragment also includes organization and feed scope, so other feeds on the page stay unchanged. To navigate to your own pages, set post-navigation="link", or supply an onOpenPost JavaScript function property (a React prop) to own navigation. The callback receives the post id and nullable URL, and needs no template. Mount <hedgehog-post> on your destination route. Either way, comments on a post are ordinary Hedgehog comments whose content id is derived from the post id, so reactions, mentions, and notifications work exactly as they do on an article.
Configure canonical URLs in your organization's Post routing dashboard setting. Use your registered site origin with a required {postId} placeholder and optional {feedId} placeholder; both expand to URL-encoded typed IDs. Your website must implement that route. Notifications then link directly to a post without waiting for a first page visit. URL configuration does not change navigation: a local post-url-template only overrides the feed's permalink. Without canonical routing, registered page URLs remain the fallback.
Account profiles also collect posts across organizations. The dashboard shows Your posts, including your own posts awaiting moderation; public profiles show Recent posts with published, unmuted posts only. Both post sections are hidden when empty. Comments keep their existing empty state. Profile post links use canonical routing or registered detail/feed pages; the profile widget below remains a profile photo manager.
On web, iOS, and Android, your own avatar in post and comment composers, post feed/detail cards, and comment cards (including replies) opens the profile-photo picker without leaving the widget. Other authors' avatars open their public profile. The picker retains a link to your full dashboard profile.
Widget attributes
Every widget accepts these two attributes:
| Attribute | Available on | Description |
|---|---|---|
| organization-id | All nine widgets | Your typed organization UUID, copied from the dashboard. Required on every widget. |
| theme-mode | All nine widgets | Selects the light or dark widget palette (defaults to light). The SDK does not auto-detect the system theme. |
The remaining attributes are widget-specific:
| Attribute | Available on | Description |
|---|---|---|
| id | Comments, reactions, live comments, and live reactions | A stable external content identifier (a slug or URL). The SDK derives its tenant-bound Content UUID and uses that typed ID for reads and writes. |
| target-type | Reactions and live reactions | Explicit target kind: content (default, id is external) or comment (id is a typed Comment:<uuid>). |
| token | Every widget except profile | Optional pre-issued member access token for a host-managed session. Omit it to use built-in OAuth. |
| theme-name | Every widget except profile | Render a specific theme pack available to your organization instead of the active one. Unknown names fall back to the active theme. |
| picker-name | Comments, reactions, post feed, post detail, and live reactions | Which named reaction picker to offer (org pickers take precedence over global). Unknown names fall back to the built-in standard picker. |
| skip-server-theme | Live comments, live reactions, post feed, and post detail | Bare boolean attribute that prevents the widget from fetching and applying the server theme pack. |
| root-content-id | Reactions and notifications | A typed Content:<uuid>. On reactions with target-type comment it names the content the comment belongs to, which is where live reaction updates arrive (ignored for content targets). On notifications it optionally restricts the account feed to one root content item. |
| page-url | Comments, post feed, and post detail | Optional canonical URL of the page hosting this widget. Must be on your registered site origin. Registers the page so notifications can show which page they are about and deep-link back to the comment or post. |
| disable-reactions | Comments, post feed, and post detail | Hide reactions on each comment or post. |
<hedgehog-posts>, <hedgehog-post> and <hedgehog-account-posts> additionally accept:
| Attribute | Available on | Description |
|---|---|---|
| feed-id | Post feed | A stable external key naming the feed; when omitted the feed is called default. The SDK derives its tenant-bound PostFeed UUID from it exactly as it derives Content UUIDs from id. |
| post-url-template | Post feed | Local permalink override, such as https://example.com/community/posts/{postId}; {postId} is the URL-encoded typed Post id. Does not change navigation or configure notification URLs. |
| post-navigation | Post feed | inline (default) opens detail inside the feed; link follows the permalink, falling back to inline if no URL exists. A host onOpenPost callback takes precedence. |
| profile-url-template | Comments, post feed, post detail, live comments, and profile | Where a member avatar links, as a URL with a {handle} placeholder (absolute or relative to the API base). Defaults to the public profile page. A host onOpenProfile callback takes precedence and owns navigation. |
| account-id | Account posts | The full typed Account:<uuid> whose published posts in this organization are listed, newest first, with the same cards as the feed and no composer. |
| post-id | Post detail | The full typed Post:<uuid> to render, supplied by your route or application state. No feed widget is required. |
| disable-comments | Post feed and post detail | Hide the comment thread under each post, even when the organization allows comments. |
<hedgehog-profile> intentionally exposes only organization-id and theme-mode. It is account-scoped, takes no content ID or host token, and signs viewers in through its built-in OAuth flow or an existing cached session.
React 19
React applications can use the typed adapter from @hedgehog/sdk-web/react. It renders the same Vue-powered custom elements, while exposing camelCase props, React callbacks, and refs. In Next.js App Router and other React Server Component applications, put the widgets in a client component as shown below. The package is safe to import during server rendering; the widget upgrades in the browser.
Programmatic client
Building custom UI? The typed HedgehogClient from @hedgehog/sdk-web exposes the same API the widgets use — comments, posts, reactions, notifications, and the live features. Pass null as the token to start unauthenticated, or a member access token for host-managed sessions; rotate it later with client.setToken(...).
Native mobile SDKs
Batteries-included widgets for iOS and Android — the same comments, posts, reactions, and notifications, with sign-in built in.
iOS — Swift
A SwiftUI view, drop-in with a single call. iOS 16+, added via Swift Package Manager with no external dependencies. Register an OAuth URL scheme in your Info.plist and share one HedgehogSocket across widgets. Pass the optional token: parameter to inject a host-managed session (SSO).
Android — Kotlin
A Jetpack Compose composable that mounts comments, reactions, and presence. Add the Gradle dependency and declare the OAuth redirect activity in your manifest.