HomeGet started

PreviousNext

Introduction

Web components for your TfL projects. Use them with tfl-ts for live data, or alone for the look.

1. Get a free TfL key from the TfL API portal

Subscribe to 500 Requests per min, then copy Primary or Secondary from Profile into .env.local. app_id has been unused since Jan 2021.

TFL_APP_KEY=your-primary-or-secondary-key

2. Set up a typeface (optional)

Components use your app's font by default. The official Johnston font requires a licence from TfL (see Licensing and brand use). This site uses the free TfL-inspired Hammersmith One. Or if you have Adobe subscription, a closer match is P22 Underground, see Typography for more details.

3. Install and render

Start from a Next.js app with shadcn already initialised. The command copies the board source into your repo and installs tfl-ts.

pnpm dlx shadcn@latest add https://tfl.manglekuo.com/r/rail-arrivals-board.json

(Quick and easy) Calls TfL from the browser, AKA client side. Anyone can right click dev tools and see your TfL key.

import { useEffect, useState } from "react"
import TflClient, { type RealtimePrediction } from "tfl-ts"
import { RailArrivalsBoard } from "@/components/tfl/arrivals/rail-arrivals-board"

const tfl = new TflClient({ appKey: import.meta.env.VITE_TFL_APP_KEY })

export default function Page() {
  const [data, setData] = useState<RealtimePrediction[]>([])

  useEffect(() => {
    let cancelled = false

    const load = async () => {
      const arrivals = await tfl.stopPoint.getArrivals({
        stopPointIds: ["940GZZLUOXC"],
        sortBy: "timeToStation",
      })
      if (!cancelled) setData(arrivals)
    }

    void load()
    const id = setInterval(load, 20_000)
    return () => {
      cancelled = true
      clearInterval(id)
    }
  }, [])

  return <RailArrivalsBoard data={data} stopName="Oxford Circus" />
}

You should see something like this:

localhost:3000

Still having trouble? See Troubleshoot.