Outpost Community Demo

Embedding Outpost on Your Website

By top-outpost-ninja ·

Want to bring your community directly into your existing website? Outpost’s embeddable widget lets you integrate discussions without sending users to a separate site — and with Embed SSO, your users stay signed in seamlessly.


Quick Start

Add this snippet wherever you want your community to appear:

<div id="outpost-embed"></div>
<script
  src="https://outpost.ninja/embed.js"
  data-community="your-community-slug"
></script>

That’s it. One script tag, and your entire community loads inside an auto-resizing iframe.


Enabling Embedding

  1. Go to Admin Settings → Embeddings
  2. Toggle Enable Embedding on
  3. Copy the embed code from the Getting Started tab

Optionally, configure Allowed Domains to restrict which websites can embed your community. If left empty, any domain can embed it.


Three Embed Modes

Full Community (Default)

The complete community experience — sidebar navigation, categories, search, profiles, and all features:

<script
  src="https://outpost.ninja/embed.js"
  data-community="your-slug"
></script>

Feed Widget

A compact topic list, perfect for sidebars or specific content sections. Filter by category, tag, or keyword:

<!-- Filter by category -->
<script
  src="https://outpost.ninja/embed.js"
  data-community="your-slug"
  data-mode="feed"
  data-category="feature-requests"
></script>

<!-- Filter by tag -->
<script
  src="https://outpost.ninja/embed.js"
  data-community="your-slug"
  data-mode="feed"
  data-tag="bug-report"
></script>

<!-- Filter by keyword -->
<script
  src="https://outpost.ninja/embed.js"
  data-community="your-slug"
  data-mode="feed"
  data-context="pricing"
></script>

Single Topic

Embed one specific discussion thread — ideal for docs pages, knowledge base articles, or blog post comments:

<script
  src="https://outpost.ninja/embed.js"
  data-community="your-slug"
  data-mode="topic"
  data-topic="your-topic-slug"
></script>

Theme & Styling

Make the embed match your website’s design with data attributes. All are optional — only override what you need:

Attribute Description Example
data-theme-mode Force light or dark "light" or "dark"
data-theme-primary Accent/brand color "#6366f1"
data-theme-bg Base background "#ffffff"
data-theme-surface Card background "#f8fafc"
data-theme-elevated Elevated elements "#f1f5f9"
data-theme-text Primary text color "#0f172a"
data-theme-border Border color "rgba(0,0,0,0.1)"
data-theme-font Font family "'Inter', sans-serif"
data-theme-radius Border radius (px) "8"
data-theme-transparent Transparent background "true"
data-css Custom CSS URL "https://your-site.com/outpost.css"
data-compact Dense spacing "true"

Full example:

<script
  src="https://outpost.ninja/embed.js"
  data-community="your-slug"
  data-theme-mode="light"
  data-theme-primary="#6366f1"
  data-theme-bg="#ffffff"
  data-theme-surface="#f8fafc"
  data-theme-text="#0f172a"
  data-theme-font="'Inter', sans-serif"
  data-theme-radius="8"
></script>

Sizing & Layout

Auto Height (Default)

The iframe automatically resizes to match its content. No scroll bars, no fixed height — it just fits.

Fixed Height with Scroll

For a contained widget with internal scrolling:

<script
  src="https://outpost.ninja/embed.js"
  data-community="your-slug"
  data-height="calc(100vh - 80px)"
></script>

Custom Container

Target a specific div instead of the default:

<div id="my-forum"></div>
<script
  src="https://outpost.ninja/embed.js"
  data-community="your-slug"
  data-container="my-forum"
></script>

Centered, Constrained Width

<div style="max-width: 1200px; margin: 0 auto;">
  <div id="outpost-embed"></div>
  <script
    src="https://outpost.ninja/embed.js"
    data-community="your-slug"
  ></script>
</div>

Authentication in Embeds

By default, when a user clicks "Sign In" inside the embed:

  1. A popup window opens with the Outpost login page
  2. The user authenticates via magic link
  3. The popup closes and the embed refreshes with the authenticated session

This works out of the box with no configuration. But for a seamless experience where users are already signed into your app, use Embed SSO.


Embed SSO (Single Sign-On)

Embed SSO lets your users access the community without a separate login. If they’re signed into your app, they’re signed into Outpost.

How SSO Works

Your Frontend  →  Your Backend  →  Outpost API  →  Embed iframe
  1. Your frontend requests an Outpost SSO token from your backend
  2. Your backend calls Outpost’s token endpoint with the user’s email and name
  3. Outpost returns a one-time token (valid for 120 seconds)
  4. You pass the token to the embed script via data-user-token
  5. The embed exchanges it for a session — the user is logged in

Step 1: Generate an SSO Secret

  1. Go to Admin Settings → Embeddings → SSO tab
  2. Click Generate Secret
  3. Copy the secret (format: opsk_...) — it’s only shown once
  4. Store it securely in your backend’s environment variables

Step 2: Create a Backend Endpoint

Your backend mints Outpost tokens for authenticated users. Here are examples for common stacks:

Node.js / Express:

app.post('/outpost-token', requireAuth, async (req, res) => {
  const response = await fetch(
    'https://outpost.ninja/api/community/YOUR_SLUG/embed/sso/token',
    {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        secret: process.env.OUTPOST_SSO_SECRET,
        email: req.user.email,
        display_name: req.user.name,
      }),
    }
  );
  const data = await response.json();
  res.json({ token: data.token });
});

Next.js (App Router):

import { getServerSession } from 'next-auth';

export async function POST(req: Request) {
  const session = await getServerSession();
  if (!session?.user?.email) {
    return Response.json({ error: 'Unauthorized' }, { status: 401 });
  }

  const res = await fetch(
    `https://outpost.ninja/api/community/YOUR_SLUG/embed/sso/token`,
    {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        secret: process.env.OUTPOST_SSO_SECRET,
        email: session.user.email,
        display_name: session.user.name ?? '',
      }),
    }
  );

  return Response.json(await res.json());
}

Step 3: Pass the Token to the Embed

On your frontend, fetch the token and inject it into the embed script:

async function loadOutpostEmbed() {
  let ssoToken = null;

  if (userIsSignedIn) {
    try {
      const res = await fetch('/outpost-token', {
        method: 'POST',
        headers: { Authorization: `Bearer ${idToken}` },
      });
      if (res.ok) {
        const data = await res.json();
        ssoToken = data.token;
      }
    } catch (err) {
      console.warn('SSO token fetch failed:', err);
    }
  }

  const script = document.createElement('script');
  script.src = 'https://outpost.ninja/embed.js';
  script.setAttribute('data-community', 'YOUR_SLUG');
  if (ssoToken) {
    script.setAttribute('data-user-token', ssoToken);
  }
  document.body.appendChild(script);
}

Or if the token is available at render time:

<script
  src="https://outpost.ninja/embed.js"
  data-community="your-slug"
  data-user-token="the-token-from-your-backend"
></script>

SSO Security Details

  • Tokens are single-use — deleted from Redis immediately after exchange
  • Tokens expire after 120 seconds
  • The SSO secret is stored as a SHA-256 hash — Outpost never stores the raw secret
  • Session cookies are set as httpOnly, SameSite=None, Secure
  • If the user doesn’t exist in Outpost, they’re automatically created and added to the community

Allowed Origins

Restrict which domains can embed your community:

  1. Go to Embeddings → Getting Started tab
  2. Add your domains under Allowed Domains (one per line):
    https://your-website.com
    https://app.your-website.com
    https://docs.your-website.com
    
  3. If left empty, any domain can embed your community

The Embed Layout

The embedded community uses a minimal layout optimized for iframe display:

  • Streamlined header with logo, title, theme toggle, and sign-in
  • No full-width banner image
  • Collapsible mobile navigation
  • "Powered by Outpost" footer (removable on paid plans)
  • Transparent background option for blending with your site

All community features work inside the embed — posting, reactions, search, DMs, profiles, and notifications.


Use Cases

Scenario Recommended Setup
Documentation site Feed widget filtered by category below each doc page
Product page Feed widget with data-tag="feature-requests"
Blog comments Single topic mode per blog post
Course platform Full community or feed filtered by lesson category
SaaS dashboard Full community with SSO for seamless auth
Knowledge base Single topic mode for each article’s discussion

PostMessage API

For advanced integrations, the embed communicates with your page via window.postMessage:

Message Type Direction Purpose
outpost-resize Embed → Parent Height change notification
outpost-url-change Embed → Parent Internal navigation (for deep linking)
outpost-auth Embed → Parent User clicked sign in (triggers popup)
outpost-auth-complete Parent → Embed Auth popup closed successfully
outpost-sso-token Parent → Embed Deliver SSO token on load

You can listen to these events to sync your app’s URL, track navigation, or trigger custom behaviors.


Tips

  • Use SSO if your users are already authenticated — the seamless experience is worth the setup
  • Match your theme using the data-theme attributes for a native feel
  • Use feed mode for focused, contextual discussions on specific pages
  • Set allowed origins in production to prevent unauthorized embedding
  • Test in incognito to verify the non-authenticated experience works correctly

Embedding transforms Outpost from a standalone platform into a composable building block for your web presence.