npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@peerpage/embed-angular

v0.5.0

Published

Angular wrapper for the Peerpage embed — a typed <peerpage> standalone component over the framework-agnostic <peerpage-embed> custom element. Self-contained (bundles @peerpage/embed-element); the only Peerpage code that runs in the host origin, and it exe

Readme

@peerpage/embed-angular

Trust model (read this first): this package is the only Peerpage code that runs in your app's origin, and it executes nothing generated. It is a thin, typed Angular component over the framework-agnostic <peerpage-embed> custom element (@peerpage/embed-element): it fetches a short-lived (≤5-minute) identity token from your own backend — by default a same-origin request so a cookie session applies, or, for Bearer-token apps (most SPAs), via a tokenProvider you supply (see Inputs). Either way your own credential is never forwarded to Peerpage. It then mounts Peerpage's runtime as an iframe on the platform origin (or, when you opt in per-tenant, inline). Every AI-built page runs in that runtime, never in your page. This wrapper adds zero new network calls of its own.

Install

npm install @peerpage/embed-angular

@angular/core and @angular/common (>= 18) are peer dependencies — it uses your app's Angular.

Use it like a normal Angular component

Import the standalone PeerpageComponent and drop the <peerpage> tag. No CUSTOM_ELEMENTS_SCHEMA, no stringly-typed attributes — typed @Input()s with full template type-checking:

import { Component } from "@angular/core";
import { PeerpageComponent } from "@peerpage/embed-angular";

@Component({
  selector: "app-workflows",
  standalone: true,
  imports: [PeerpageComponent],
  template: `<peerpage slug="flag-orders" tenantId="acme"></peerpage>`,
})
export class WorkflowsComponent {}

platformUrl / apiUrl default to Peerpage's hosted platform, so only slug + tenantId are required. Bind dynamic values the usual way ([slug]="slug", [tenantId]="tenant", …).

Inputs

| Input | Required | Description | | -------------- | :------: | --------------------------------------------------------------------------------------------------- | | slug | ✓ | The page to open, e.g. "flag-orders". | | tenantId | ✓ | Your Peerpage tenant id, e.g. "acme". | | platformUrl | | The Peerpage runtime origin. Default "https://run.getpeerpage.com"; override for self-host / dev. | | apiUrl | | The Peerpage API origin (where /embed/config lives); drives inline/iframe. Default "https://api.getpeerpage.com". | | tokenPath | | Path on your backend that mints the identity token. Default "/peerpage/token". | | tokenProvider| | A () => Promise<string> your app supplies when it authenticates with a Bearer token held in JS (most SPAs — no same-origin cookie session). See below. | | width | | Outer-box width, any CSS length. Default "100%". | | height | | Sizing model: "fill" (default), "auto" (grow with content), or a CSS length ("720px", "80vh"). Iframe mode; inline sizes to the host flow. | | minHeight / maxHeight | | Optional bounds on the box height (any CSS length) — handy with height="auto". | | className | | Your CSS class on the embed box — border, radius, shadow, margin, background. |

The embed box is your own element in your origin, so styling it is safe — none of this reaches the runtime inside. Size it with the inputs, e.g. a fixed-height card:

<peerpage slug="flag-orders" tenantId="acme"
  width="480px" height="auto" minHeight="240px" maxHeight="80vh"
  className="card"></peerpage>

For one-off inline styles you can also bind natively on the <peerpage> host element ([style.border]="…") — the embed fills the host, so host-level box styles wrap it.

Bearer-token apps (tokenProvider)

The default token flow does a same-origin POST /peerpage/token with credentials: "include" — that only works when your app authenticates with a cookie session. Most SPAs instead hold a Bearer JWT in JS (localStorage / an auth store) and attach it via an HTTP interceptor the embed's own fetch does not go through — so /peerpage/token would receive no Authorization header and return 401. For those apps, pass a tokenProvider that mints the token with your own credential attached:

@Component({ imports: [PeerpageComponent], template: `
  <peerpage slug="flag-orders" tenantId="acme" [tokenProvider]="mintToken"></peerpage>
` })
export class WorkflowsComponent {
  mintToken = async () => {
    const res = await fetch("/peerpage/token", { method: "POST", headers: { Authorization: `Bearer ${this.auth.accessToken}` } });
    if (!res.ok) throw new Error(`token ${res.status}`);
    return (await res.json()).token;
  };
}

Your credential goes only to your own /peerpage/token — it is never forwarded to Peerpage.

How it works

PeerpageComponent registers the <peerpage-embed> custom element (a side-effect import of @peerpage/embed-element) and mounts it imperatively into the component's host with your inputs mapped onto its attributes — so the element always boots with its required attributes present (no Angular binding-timing race) and you never touch CUSTOM_ELEMENTS_SCHEMA. Under Angular SSR it renders nothing on the server and mounts in the browser. Prefer the raw <peerpage-embed> custom element for non-Angular hosts.