Documentation

Troubleshooting

Relay instead of direct, a code that will not resolve, a display that will not wake.

The code will not resolve

Three causes, in order of likelihood:

  • The room ended. Rooms close after five quiet minutes (nothing attached to them, and the room page neither open nor in front of you) and release their code. Open a new session from the script. Leaving the room page up and visible while you fetch the other device is what keeps this from happening.
  • Different accounts. The second device is signed in as someone else. A personal account on the phone and a work account on the laptop is the classic version. Rooms are scoped to an account, so the lookup genuinely finds nothing. Check the avatar in the header on both.
  • A mistyped character. The alphabet excludes lookalike characters, but it is still worth reading it back.

It says Relay, not Direct

No direct route could be negotiated, so messages go through the realtime relay. Everything works; it is a matter of tens of milliseconds. Common causes:

  • Corporate or campus networks that block UDP or STUN.
  • Symmetric NAT on one side, which STUN alone cannot get through.

The upgrade is retried in the background for about a minute, then left alone. That is deliberate: a pair that cannot reach each other will not start being able to.

Same Wi-Fi and still on the relay? Two causes account for most of it, and neither is something the app can work around:

  • Client isolation. Guest and venue networks very often block traffic between devices on the same access point, on purpose. Everything reaches the internet; nothing reaches the laptop two feet away. A phone hotspot is the quickest way to confirm it: if the badge flips to Direct there, the network was isolating clients.
  • A VPN on either device. It changes the route out and usually hides the local addresses that would otherwise let the two devices find each other on the LAN.

Beyond that, direct routes on genuinely hostile networks need a TURN server, which the hosted instance does not run. Expect the relay there, and plan around the few extra milliseconds rather than the badge.

The badge says “Catching up”

The realtime channel is not carrying traffic, so this device is reading the room’s saved position over HTTPS instead of receiving it from the other device. The session still works; it is a couple of seconds behind, and it corrects itself as soon as the channel recovers.

It usually means a network that blocks WebSockets, or a socket that died while the device was asleep. Bringing the app back to the foreground forces a reconnect, as does moving to a different network.

The two screens lag apart

A small, constant offset is normal and is just the network delay; the follower extrapolates to hide it. If they are visibly out of step:

  • Check the latency figure in the badge. Anything over about 400ms will be noticeable.
  • If one device was in the background, bring it forward. Browsers throttle timers in background tabs, and the follower catches up within a second of returning.
  • If they are on genuinely different text (one shows an old version), the room snapshot and the script have diverged. Open the room page and pull the edits in.

The display dims or sleeps

The display asks for a screen wake lock, which most modern browsers honour. It is dropped whenever the tab is hidden and re-requested when it comes back. If your screen still sleeps:

  • The wake lock needs a secure context. Over plain HTTP on a LAN address it will not be granted.
  • Low-power mode on iOS can override it.
  • Installing Teleprompt to the home screen and running it full screen is the most reliable configuration.

Mirrored text looks wrong

Mirror is for a beam-splitter, where you read the reflection. Looking at the screen directly, mirrored text is supposed to look backwards. Judge it in the glass.

If the reflection is upside down rather than backwards, you want Flip as well; that is the face-up-under-glass configuration.

iOS oddities

  • Add to Home Screen is Safari-only. Chrome and Firefox on iOS cannot install a web app.
  • An installed app has its own session. You will sign in once inside the installed app even if you were signed in in Safari.
  • Haptics on the remote need a real tap. The vibration API is unavailable in Safari, so the remote is silent there; the controls still work.

A device is stuck connecting

Press Retry next to the connection badge. It appears once a join has actually failed, and forces a fresh one immediately rather than waiting out the backoff.

Behind that, three things happen on their own: a join that never answers is abandoned after twelve seconds and retried; repeated failures drop the shared socket entirely and build a new one, on the assumption that the channel is not the problem; and the session keeps working off the saved position in the meantime, which is what the badge means by Catching up.

The badge shows Connecting or Reconnecting for more than a few seconds:

  1. Reload the page. Rejoining is cheap and re-announces presence.
  2. Confirm the other device is actually on the room page, not the lobby.

Sign-in problems

“That account has no verified email address” means the provider handed back an address it has not verified. Teleprompt recognises your other devices by email, so it refuses those rather than risk putting you in somebody else’s account. Verify the address with the provider and try again.

Signed in with the other button and got a new account? That should not happen: accounts sharing a verified email are linked, so Google on the laptop and GitHub on the phone land in the same place. If the two providers hold different email addresses, they are two different people as far as Teleprompt is concerned, and the join code will not resolve.


Problems with an instance you host yourself (the health check, the database endpoint, sign-in that only fails in production) are on Deployment troubleshooting.