Using the viewer¶
This page walks through the web viewer screen by screen. For signing in and sharing, see Logins, viewer accounts and share links. For colours, see Themes and wallpaper. For notifications, see Live updates and notifications.
Layout¶
The viewer has three panes:
- The sidebar on the left holds the chat list and search.
- The chat pane in the middle shows the messages of the open chat.
- The info panel on the right opens when you click the chat information button in the chat header.
The viewer only reads the archive. It never contacts Telegram. The interface is in English only.
VIEWER_TIMEZONE sets the time zone for every time the viewer shows. It defaults to Europe/Madrid. If the zone name is unknown, the viewer logs a warning and uses UTC.
On a desktop you can resize the sidebar and the info panel. Drag the handle between two panes, or focus the handle and press Left or Right to move it 16 px at a time.
| Pane | Width |
|---|---|
| Chat list | 300 to 960 px, a quarter of the window by default |
| Info panel | 260 to 640 px, 320 px by default |
| Messages | always at least 360 px |
Each browser remembers its own widths.
Chat list¶
The top of the sidebar shows folder tabs. All Chats comes first, then one tab per Telegram folder, with the folder's emoji or a folder icon and its chat count. The tabs only appear when the archive holds at least one folder. In All Chats, an Archived Chats row appears when you have archived chats in Telegram.
Chats load 50 at a time. Scroll down and the next 50 load. Each row shows ID: <id>, the chat's Telegram id.
When you can see more than one Telegram account, each row carries a chip with the account's label. See Multiple accounts.
The sidebar also shows Last backup with the time of the most recent backup. When the listener is running, the same line shows Real-time sync with a green dot.
Search¶
One field at the top of the sidebar searches chats and messages together. Results appear 300 ms after you stop typing.
- Chats match on title, first name, last name or username.
- Messages use full-text search that matches the start of words. The newest match comes first. Results load 20 at a time as you scroll, and the list stops at 5,000 with "Showing the first 5,000 matches".
Use Up and Down to move through both sections, Enter to open a result, and Esc to clear the field. A second Esc leaves the field.
A hit found in a voice transcript carries the label "Matched in the transcript".
If the archive has no full-text index yet, the message section says so. The index is created by the database migrations, which shipped in 8.3.0. The backup image applies them when its container starts. On a pip install, run telegram-archive migrate. A SQLite build without FTS5 keeps the older substring search.
You can paste a Telegram link into the field. A t.me/c/<id>/<msg> or t.me/<username>/<msg> link opens that message when the chat is in the archive. Otherwise the sidebar says "That link points at a chat this archive does not hold".
Inside an open chat, the search box in the chat header searches that chat only, with the same 300 ms delay.

Reading messages¶
Text¶
Messages keep their Telegram formatting: bold, italic, underline, strikethrough, code, preformatted blocks, quotes and spoilers. Click a spoiler, or focus it and press Enter or Space, to reveal it.
Only http, https and tg links are clickable. Mentions are highlighted. Web addresses that start with http:// or https:// become links even without formatting. Email addresses become links when Telegram marked them as such.
A #hashtag or $CASHTAG opens a tag view with three tabs: This Chat, My Messages and All Chats.
Replies and forwards¶
A reply shows a quote of the message it answers. Click the quote to jump to the original.
A forward shows "Forwarded from" and the source. When the source chat is also in the archive, click the header to open the original message.

Albums¶
Photos and videos sent together render as one grid:
| Items | Grid |
|---|---|
| 2 | two columns |
| 3 | two on top, one below |
| 4 | two by two |
| 5 or more | three columns |
The caption comes from whichever item carries it. The viewer renders only the first message of an album and does not show reactions on the other messages.

Media¶
- Round videos play in place as a circle, muted, while they are on screen. Click one to turn the sound on or off. They never open in the lightbox.
- GIFs loop while they are on screen and pause when you scroll away.
- Stickers in
.webpshow as images up to 200 px wide. Other stickers show the text "Animated Sticker". - Polls and quizzes show each answer with a percentage bar and the total votes.
- Dice, venues, invoices, stories, giveaways, live locations and games show as a chip.
- Link previews show the archived card with site name, title, description and image.
When a file is not in the archive, the bubble says why. Why media is missing in the viewer lists each message and the setting behind it.
Voice messages and other audio can carry a transcript that opens under the player. See Voice transcription.
Reactions, edits and deletions¶
Reactions show as chips with the emoji and, when above one, the count.
An edited message shows "edited", or "edited(N)" when it was edited N times. Click it to open the Versions drawer, which lists up to 100 earlier texts.
A deleted message stays in place, faded, with a "deleted" marker. The archive only learns about deletions when the listener runs with LISTEN_DELETIONS=true or the backup runs with SYNC_DELETIONS_EDITS=true. Both are off by default. With DELETION_MODE=soft, the default, the row is kept and marked. With hard it is removed.
Service messages¶
Joins, title changes and other chat events show as centred pills. Click the name of the person who did it to open their details.
When a group was converted to a supergroup, a banner says "This group continues as a supergroup" or "Migrated from
Moving through time¶
Pinned messages¶
A banner under the chat header shows the current pinned message. When more than one message is pinned, the banner also shows the position as "N of M". Click the text to scroll to that message and move the banner to the next pin. This only works for a pinned message already loaded in the pane. For older pins, click the pin button to open the Pinned Messages view.
Jump to the newest message¶
A round button with a down arrow appears in the bottom right corner. It shows when you scroll more than 200 px above the newest message, or when new messages arrive that you have not seen. A badge counts the unseen messages, up to 99+. Click it to return to the newest message.
Jump to a date¶
While you scroll, a pill at the top of the pane shows the day you are looking at. Click it, or any date separator, to open Jump to Date. Days that have messages carry a dot. The latest date you can pick is today in VIEWER_TIMEZONE. Press Esc to close the dialog.
Links to a message¶
Every message has an address of the form /?chat=<ref>&msg=<id>. Opening it loads the chat around that message.
To get the link, select the message with the info panel open, or open the sender's details, and click Copy message link. On a plain http address the browser does not allow copying, so the link appears in a notice instead.
The link names the chat by its chat ref, not its Telegram chat id. A chat ref is a random 22-character handle that never changes.
Forum topics¶
Opening a forum shows its topics first. Each topic has its icon, a pinned or closed marker when it applies, and its message count. Topic 1 is General. When the archive holds no topics for the forum, a View all messages button opens the whole chat.

Shared media¶
The Shared Media Gallery button in the chat header opens the chat's files in three tabs:
| Tab | Holds |
|---|---|
| Photos & Videos | photos, videos, GIFs and round videos, as a grid |
| Voice | voice messages and audio, with a filter box that matches the file name or the transcript |
| Files | documents, each with download and go-to-message buttons |
Items load 50 at a time. Click Load more for the next page.
Photos, videos and GIFs open in the lightbox. A round video tile jumps to its message. Press Esc to close the lightbox and Left or Right to move between items. Files have a download button and a go-to-message button. Download buttons are hidden for no-download logins.
How thumbnails are made and cached is on Media downloads.

Info panel¶
The info panel shows the open chat:
- avatar, name, and member or subscriber count
- earlier profile photos the archive recorded
- description or bio, username and Telegram ID
- account chips, when more than one account is visible
- shortcuts into the shared media
With the panel open, click a message to select it. The panel then also shows:
- sender
- sent time
- edit time
- the message it replies to
- forward source
- message id
- album id
- pinned or deleted state
- its files, with a download button
With the panel open, Up and Down move the selection to the next message, and Esc closes the panel.
The master login also sees each file's Archive path and a Copy path button. Other logins do not.
Open and Show in folder¶
Two more buttons, Open and Show in folder, appear for the master login when the viewer host sets MEDIA_OPEN_CMD or MEDIA_OPEN_PATH_CMD. Use them only when the viewer runs directly on your own computer, outside Docker.
Each variable holds a shell command. The viewer replaces %PATH%, %DIR% and %FILENAME% with the shell-quoted file path, its folder and its name. Open only accepts images, videos, audio and PDF files.
# macOS example for a native run
export MEDIA_OPEN_CMD='open %PATH%'
export MEDIA_OPEN_PATH_CMD='open -R %PATH%'
These buttons run a shell command on the viewer host
Anyone who can use them runs that command. See Commands that run on the viewer host.
Audio player¶
Playing a voice message or an audio file opens one player bar for the whole app. It has previous and next buttons, a seek bar and speeds of 0.5x, 1x, 1.5x and 2x. The speed buttons are hidden on screens narrower than 640 px.
Voice and music each keep their own speed. Playback continues when you switch chats. When one item ends, the player moves on to the next audio in the chat.
No-download logins cannot play audio. Their play buttons are disabled and the player bar does not appear.
What changed¶
The clock button in the sidebar header opens What changed. It lists deletions, edits and new voice transcripts, newest first. Pick a window of Last 24 hours, 7 days, 30 days or All time. Entries load 50 at a time.
Deletions appear here only when the archive learns about them: the listener runs with LISTEN_DELETIONS=true or the backup runs with SYNC_DELETIONS_EDITS=true. Both are off by default. With DELETION_MODE=hard a deleted row is removed instead of kept.
Export a chat¶
The Export Chat to JSON button in the chat header downloads the open chat as a JSON file. You can set a from date, a to date, both or neither. A to date on its own includes that whole day.
The file is named <title>_export.json. It holds the chat, the filters you used, the messages and their earlier versions. It holds no media files.
No-download logins cannot export.
Statistics¶
The Stats dropdown in the sidebar header shows the number of chats, messages and media files, the storage used and when the numbers were calculated. The dropdown appears once the numbers have been calculated for the first time.
The numbers are cached. These recalculate them:
- The viewer, once a day at
STATS_CALCULATION_HOURinVIEWER_TIMEZONE. The default hour is 3. - The viewer, once at startup, if the numbers were never calculated.
- The backup, after each run.
- The master login, on request, through
POST /api/stats/refresh.
Logins restricted to some chats see counts for their own chats only. The message, media and size figures in a chat's header are cached for 60 seconds.
SHOW_STATS=false hides the dropdown. The statistics API still answers.
Setting the stats hour under Docker
The stock docker-compose.yml does not pass STATS_CALCULATION_HOUR to the viewer. Add it to the viewer's environment: block. See Environment variables.
Archive status¶
The master login has an Archive Status button, the heart icon next to the user name at the top of the sidebar. It opens a panel with:
| Row | Shows |
|---|---|
| Backup | running now, the time of the last run, or never ran |
| Listener, one row per Telegram account | active since when, or not running |
| Media pipeline | files downloaded, pending, given up and skipped by settings |
| Stats freshness | when the statistics were last calculated |
| Transcription | off, on with no server configured, server not detected yet, or the server's name and version |
| Database | SQLite or PostgreSQL, and its size |
On a phone¶
Below 768 px wide, the layout changes:
- The sidebar hides once a chat is open, and the chat takes the full width.
- A back button in the chat header returns to the chat list.
- The info panel covers the whole screen.
- Header buttons get 44 px touch targets.
- The resize handles are hidden.

Install as an app¶
Browsers that support it can install the viewer as an app. It then opens in its own window without the browser toolbar.
It does not work offline. The app needs the viewer to be reachable, as the web page does.
After you upgrade the viewer, reload any open tabs or app windows. An open page keeps using the old version until it reloads.
Keyboard¶
| Key | Where | Does |
|---|---|---|
| Esc | search field | clears the field, then leaves it |
| Esc | info panel, lightbox, Versions drawer, Jump to Date, sender details | closes it |
| Up Down | search results | moves between chats and messages |
| Up Down | open info panel | selects the previous or next message |
| Left Right | lightbox | previous or next item |
| Left Right | focused resize handle | resizes the pane by 16 px |
| Enter | search results | opens the highlighted result |
| Enter Space | spoiler, round video | reveals the spoiler, toggles the sound |
| Tab | Jump to Date, sender details | stays inside the dialog |
There are no single-letter shortcuts such as j and k.