Git-Native Config

Your entire tracking configuration is a TypeScript file. Review it in PRs. Test it in CI. Roll it back with git revert.

junction-config.ts
import type { CollectorConfig } from "@junctionjs/core";
import { ga4 } from "@junctionjs/destination-ga4";
import { amplitude } from "@junctionjs/destination-amplitude";
import { meta } from "@junctionjs/destination-meta";
import { contracts } from "./contracts";

export const config: CollectorConfig = {
  name: "orbit-supply",
  environment: "production",

  // ① Consent: queue events while user decides, respect privacy signals
  consent: {
    defaultState: {},          // No consent assumed on load
    queueTimeout: 10_000,      // 10s queue before dropping
    respectDNT: true,          // Honor Do Not Track
    respectGPC: true,          // Honor Global Privacy Control
  },

  // ② Destinations: each declares its own consent requirements
  destinations: [
    {
      destination: ga4,
      config: { measurementId: "G-XXXXXXXXXX", consentMode: true },
      // consent: ["analytics"]  ← inherited from destination
    },
    {
      destination: amplitude,
      config: { apiKey: "amp_xxxxxxxxxxxx", mode: "client" },
    },
    {
      destination: meta,
      config: { pixelId: "123456789" },
      // consent: ["marketing"]  ← inherited from destination
    },
  ],

  // ③ Contracts: Zod schemas that validate every event at runtime
  contracts,

  // ④ Debug: in-page panel in dev, zero overhead in production
  debug: process.env.NODE_ENV !== "production",
};
Consent

Queue events while consent is pending. Respect DNT and GPC browser signals. Configure per-destination consent categories.

Destinations

Each destination is a typed plugin that declares its own consent requirements. Add or remove one in a PR — no UI required.

Contracts

Zod schemas validated at runtime. Invalid events are caught immediately, not discovered weeks later in a dashboard.

Debug

In-page debug panel in development. Zero runtime overhead in production. Toggle with Ctrl+Shift+J.

What This Replaces

GTM / Adobe Launch

Every change requires navigating 4+ screens. No PR. No CI. No rollback button.

  1. 1.Log into the GTM web UI, navigate to the correct workspace
  2. 2.Create a tag — pick the right template, configure fields in form inputs
  3. 3.Create a trigger — select conditions from dropdown menus
  4. 4.Link tag to trigger, hope the variable names match your dataLayer
  5. 5.Test in Preview mode (opens a separate debug window)
  6. 6.Click "Submit" — no PR, no review, no CI tests, no rollback button
  7. 7.Pray nobody broke the dataLayer contract in a code deploy

Junction

Everything is TypeScript in your repo. Ships with your app. Rolls back with git.

  1. 1.Edit junction-config.ts in your IDE
  2. 2.TypeScript catches misconfigured destinations at compile time
  3. 3.Open a PR — teammates review the exact diff
  4. 4.CI runs contract tests against your Zod schemas
  5. 5.Merge — deploys automatically with your app
  6. 6.Something wrong? git revert restores the previous config

Adding Amplitude: The Diff

This is the entire change required to add Amplitude to your analytics stack. 8 lines. In a PR. Reviewed, tested, and deployed with your code.

junction-config.ts
destinations: [
{ destination: ga4, config: { measurementId: "G-XXX" } },
+ {
+ destination: amplitude,
+ config: {
+ apiKey: process.env.AMPLITUDE_KEY,
+ mode: "client",
+ eventNameFormat: "Title Case",
+ },
+ },
],

With Junction

8 lines of TypeScript → PR → CI → merge. Done. Reviewable, testable, reversible.

With GTM

Create tag → create trigger → configure variables → link → preview → submit. 6 steps. No PR. No CI. No rollback.

Houston, we have cookies!

These cookies fuel our rockets, not your waistline. We use them to understand how you navigate the cosmos and improve your mission experience.