Toute la documentation

Démarrer

  1. 01Pour commencer
  2. 02Installation
  3. 03Suivi

Fonctionnalités

  1. 04Le tableau de bord
  2. 05Objectifs
  3. 06Liens courts
  4. 07Sources et agents IA
  5. 08Rapports par e-mail
  6. 09Vérification planifiée
  7. 10Interrogez votre IA

Référence

  1. 11Configuration
  2. 12API HTTP

Plateformes

  1. 13Serveur autonome
  2. 14PHP
  3. 15WordPress
  4. 16Drupal
  5. 17Craft CMS
  6. 18Python
  7. 19Rails
  8. 20Ruby
  9. 21Go
  10. 22Java
  11. 23.NET
  12. 24Elixir
  13. 25Rust

Confiance

  1. 26Confidentialité

Fonctionnalités

Liens courts

Les liens courts sur votre propre domaine sont comptés comme des visites et peuvent être importés depuis Umami, Dub, Bitly, Short.io, Rebrandly ou un CSV.

Runlight crée des liens courts qui redirigent où vous voulez. Chaque clic est compté comme une visite (source, pays, appareil, navigateur et toutes les balises UTM du lien court) et tenu à part de vos chiffres de visiteurs et de pages vues. Les robots sont redirigés sans être comptés.

Par défaut, les liens vivent sous /go dans votre application, comme example.com/go/sale. Servez-les avec une route de plus, montrée ici pour Next.js.

app/go/[slug]/route.ts

import { rl } from "@/lib/runlight";

export const GET = rl.linkHandler();

Changez le chemin avec runlight({ linkPath: "/l" }). Dans Express, Connect, NestJS, Fastify et Koa, le middleware shortLinks présenté dans Domaines personnalisés sert aussi /go. Dans les autres langages, /go est servi avec le reste des routes de Runlight, comme le montre la page de chaque langage.

Nouveau lien, dans le bloc Liens, prend la destination et garde l’identifiant aléatoire ou utilise celui que vous saisissez. Gérer liste tous les liens pour que vous puissiez les rechercher, les trier par date, par clics ou par nom, et modifier, copier ou supprimer chacun d’eux. Les identifiants sont uniques sur l’ensemble de vos domaines, et des milliers de liens fonctionnent sans problème.

Cliquez sur un lien pour voir ses clics au fil du temps et leur provenance.

Domaines personnalisés

Les liens peuvent aussi vivre sur un domaine à eux, comme t.example.com/sale. Configurez-en un dans Réglages, Domaines personnalisés.

  1. Faites pointer le domaine vers votre application avec un enregistrement CNAME pour un sous-domaine, ou un enregistrement A ou ALIAS pour un domaine nu.
  2. Faites en sorte que votre hébergeur accepte le domaine et le serve en HTTPS (sur Vercel ou Netlify, ajoutez-le aux domaines du projet).
  3. Ajoutez le domaine dans les Réglages. Runlight vérifie qu’il atteint votre application et vous le dit.

Un domaine de liens répond sur tous ses chemins, il ne peut donc jamais être le domaine de votre application ni celui d’un de vos sites. Il doit aussi être un nom public, donc les noms réservés aux réseaux privés, comme .internal ou .local, sont refusés. Passez origin à routes() avec l’adresse de votre application, et la première règle tient quel que soit l’en-tête Host d’une requête. Un hub connecté ne peut ajouter des domaines de liens qu’une fois origin défini, puisqu’il ne peut pas savoir sur quels noms répond votre application. Les chemins sous le tableau de bord, comme /runlight, atteignent toujours votre application, vous pouvez donc ouvrir le tableau de bord sur n’importe lequel de ses noms pour retirer un domaine.

Retirer un domaine garde ses liens, avec leurs clics et leurs statistiques. Ils passent sous /go/<slug> jusqu’à ce que vous ajoutiez à nouveau le domaine, puis ils y reviennent.

Les requêtes sur ce domaine doivent atteindre Runlight avant que les routes de votre application ne les voient. rl.linkDomainResponse(request) répond à une requête sur l’un de vos domaines de liens et renvoie null pour tout le reste, donc le reste de votre application n’est pas touché. Appelez-le en premier dans ce qui s’exécute avant vos routes. Les autres langages ont la même vérification, souvent intégrée au middleware qui sert Runlight, et la page de chaque langage montre où elle se place.

Next.js

Next.js l’exécute dans proxy.ts à partir de Next.js 16.

proxy.ts

import { rl } from "@/lib/runlight";

export async function proxy(request: Request) {
  return (await rl.linkDomainResponse(request)) ?? undefined;
}

Sur Next.js 15, nommez le fichier middleware.ts et renommez la fonction en middleware. À partir de Next.js 15.5, ajoutez aussi export const config = { runtime: "nodejs" }; pour que votre pilote de base de données puisse se charger. Avant Next.js 15.5, le middleware ne tourne que sur le runtime Edge, il lui faut donc un stockage qui y fonctionne, comme Turso en HTTP. Sans cela, utilisez des liens /go/<slug>, que le route handler sert déjà.

SvelteKit fait de même dans le hook handle de src/hooks.server.ts, avec (await rl.linkDomainResponse(event.request)) ?? resolve(event), et Astro dans src/middleware.ts, avec (await rl.linkDomainResponse(context.request)) ?? next().

Express, Connect et NestJS

shortLinks, de @runlight/sdk/node, répond aux domaines de liens et à /go/<slug>, et transmet toutes les autres requêtes sans lire leur corps. Placez-le avant vos routes.

server.ts

import { shortLinks, toNodeHandler } from "@runlight/sdk/node";

app.use(shortLinks(rl));
app.use(toNodeHandler(rl.routes().handler));

Un identifiant sans lien sur votre propre domaine continue vers votre application, et c’est donc votre propre page 404 qui y répond. Dans un serveur http simple, appelez-le sans next, et il se résout à true quand il a répondu.

ts

const links = shortLinks(rl);

createServer(async (req, res) => {
  if (await links(req, res)) return;
  // ...your app
});

Fastify

Exécutez-le dans un hook onRequest, et cédez la réponse une fois qu’il a répondu.

ts

const links = shortLinks(rl);

app.addHook("onRequest", async (req, reply) => {
  if (await links(req.raw, reply.raw)) reply.hijack();
});

Koa

ts

const links = shortLinks(rl);

app.use(async (ctx, next) => {
  if (await links(ctx.req, ctx.res)) ctx.respond = false;
  else await next();
});

Hono

ts

app.use(async (c, next) => (await rl.linkDomainResponse(c.req.raw)) ?? next());

Nuxt et h3

Un middleware serveur s’exécute avant chaque route. Il construit la requête à partir de la seule adresse et des en-têtes, car toWebRequest de h3 commencerait à lire le corps d’une requête destinée à votre application.

server/middleware/links.ts

export default defineEventHandler(async (event) => {
  const link = await rl.linkDomainResponse(new Request(getRequestURL(event), { method: event.method, headers: event.headers }));
  if (link) return link;
});

Bun, Deno et Cloudflare Workers

Vérifiez avant tout le reste dans fetch.

ts

async fetch(request) {
  const link = await rl.linkDomainResponse(request);
  if (link) return link;
  // ...the routes and your app
}

Un Worker a besoin que le domaine de liens soit routé vers lui, en plus de /runlight/*.

Réglages, Importer, Liens courts récupère les liens d’un autre service, avec leur historique de clics quand le service le partage.

Depuis Ce qui est repris
Umami Chaque lien et chaque clic, avec le pays, l’appareil, le navigateur et le référent. Connectez-vous avec une clé d’API, ou avec votre nom d’utilisateur et votre mot de passe pour un Umami auto-hébergé.
Dub Chaque clic sur les offres Business, les clics par jour sur Pro, et seulement les liens sur Free.
Bitly Les clics par jour, aussi loin que votre offre les conserve.
Short.io Les clics par jour. Short.io autorise 60 requêtes de statistiques par minute, donc les gros comptes prennent un moment.
Rebrandly Seulement les liens, car son API ne donne pas de clics datés.
N’importe quel CSV Les colonnes name, url et, en option, slug et domain.

Votre clé ou votre mot de passe est envoyé à chaque étape de l’import et n’est jamais enregistré. Les imports traitent quelques liens à la fois, ils fonctionnent donc sur les hébergeurs serverless, et vous pouvez les relancer sans risque, car les liens déjà présents sont ignorés. Les liens sur le domaine propre à l’ancien service (bit.ly, dub.sh, rebrand.ly, short.gy) gardent leur identifiant et passent sur votre propre chemin de liens. Les liens sur vos domaines de marque gardent leur domaine, qui est ajouté dans Domaines personnalisés.