---
title: Links
icon: link
description: Set up and run the Reloop links app locally.
---
> For the complete documentation index, see [llms-docs.txt](/llms-docs.txt) or the site index [llms.txt](/llms.txt). Full docs corpus: [llms-full-docs.txt](/llms-full-docs.txt). Prefer markdown URLs (append `.md`) for agent consumption. Product skill: [skill.md](/skill.md).


Contact preference center, tracked link redirects, and open-tracking pixel proxy for outbound email.

<Tip>
Run [`bun setup`](/docs/setup) once from the monorepo root before starting individual apps. Preferences need [contacts](/docs/setup/backend/contacts) and [mail](/docs/setup/backend/mail) running (`bun dev` or `bun backend:dev`).
</Tip>


## Overview

| Property | Value |
| :--- | :--- |
| **Directory** | `apps/frontend/links` |
| **Port** | `3005` |
| **Preferences** | [https://local.reloop.sh/preferences](https://local.reloop.sh/preferences) |
| **Redirect** | [https://local.reloop.sh/redirect](https://local.reloop.sh/redirect) |
| **Open tracking** | [https://local.reloop.sh/api/mail/v1/track/open](https://local.reloop.sh/api/mail/v1/track/open) |
| **Stack** | Next.js · React 19 · Tailwind CSS |


## Quick start

From the monorepo root (after [`bun setup`](/docs/setup)):

```bash
bun fe:links:dev
```

Or start every frontend together:

```bash
bun frontend:dev
```

Turbopack serves the app on port `3005`. Prefer the `local.reloop.sh` URLs above when Caddy is running.

<Warning>
Use `https://local.reloop.sh/...`, not `localhost:3005`, so redirects and cookies match production-style hosts.
</Warning>


## Environment

Committed local defaults live in `apps/frontend/links/.env` (and `.env.dev`). Fresh clones already have them; `bun env:setup` / `bun setup` recreate or merge missing keys.

```bash
NEXT_PUBLIC_URL=https://local.reloop.sh
# Must match TRACKING_SECRET in the mail backend and REDIRECT_SECRET in auth/email backends
REDIRECT_SECRET=reloop_tracking_secret_default_123

# Server-side contacts API (preferences page)
INTERNAL_API_URL=http://localhost:8014/api/contacts

# Server-side mail API (open-tracking pixel proxy)
INTERNAL_MAIL_API_URL=http://localhost:8015/api/mail

# Rybbit analytics (optional)
NEXT_PUBLIC_RYBBIT_HOST=https://app.rybbit.io
NEXT_PUBLIC_RYBBIT_SITE_ID=reloop-web
```

Preferences call [contacts](/docs/setup/backend/contacts) via `INTERNAL_API_URL`. Open-tracking proxies to [mail](/docs/setup/backend/mail) via `INTERNAL_MAIL_API_URL` (or `NEXT_PUBLIC_URL` as a fallback).

| Variable | Required | Default |
| :--- | :--- | :--- |
| `NEXT_PUBLIC_URL` | No | `https://link.reloop.sh` — base URL for redirect and preference links |
| `REDIRECT_SECRET` | No | Shared secret with mail / auth / email backends |
| `INTERNAL_API_URL` | No | `http://localhost:8014/api/contacts` |
| `INTERNAL_MAIL_API_URL` | No | Falls back to `{NEXT_PUBLIC_URL}/api/mail` |
| `NEXT_PUBLIC_RYBBIT_HOST` | No | Rybbit analytics host |
| `NEXT_PUBLIC_RYBBIT_SITE_ID` | No | Rybbit site identifier |


## Routes

| Route | Purpose |
| :--- | :--- |
| `/preferences/[token]` | Manage subscription topics and unsubscribe |
| `/redirect/[token]` | Track clicks and redirect to destination URL |
| `/api/mail/v1/track/open/[token]` | Proxy open-tracking pixels to the mail service |


## Architecture

| Layer | Detail |
| :--- | :--- |
| **[Mail](/docs/setup/backend/mail)** | Injects `/redirect/[token]` click links and open pixels in outbound HTML |
| **[Contacts](/docs/setup/backend/contacts)** | Powers preference page data |
| **Open-tracking proxy** | Custom tracking domains CNAME here; pixels proxy to mail when `/api/mail` is not on the tracking host |
| **Caddy** | Routes `/preferences*` and `/redirect*` to port `3005` |


## Commands

| Command | Description |
| :--- | :--- |
| `bun fe:links:dev` | Start dev server with Turbopack |
| `bun run --filter=fe-links build` | Compile production bundle |
| `bun run --filter=fe-links start` | Run production build |
| `bun run --filter=fe-links lint` | Run ESLint checks |


## Next

<CardGroup cols={2}>
  <Card icon="rocket" title="Setup" href="/setup">
    One-command local bootstrap
  </Card>
  <Card icon="globe" title="Port reference" href="/setup/port">
    Gateway routes and ports
  </Card>
  <Card icon="users" title="Contacts" href="/setup/backend/contacts">
    Preferences data API
  </Card>
  <Card icon="mail-single" title="Mail" href="/setup/backend/mail">
    Tracking links and open pixels
  </Card>
</CardGroup>
