feat(ui): route all in-app external links through Telegram openLink
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Has been skipped
CI / integration (pull_request) Has been skipped
CI / ui (pull_request) Successful in 49s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 59s

Extend the openLink routing from the dictionary lookup to every external
link shown inside the Mini App, so none triggers the WebView's 'open this
link?' confirmation. A shared onExternalLinkClick handler resolves the anchor
via closest() (so it also works delegated on {@html} content), backed by a
pure routeExternalLinkInTelegram decision: only inside Telegram, only an
external http(s) target=_blank link, excluding same-origin/in-app and t.me
links (t.me keeps openTelegramLink). Applied to the word-check lookup, the
About rules link, the Feedback operator-reply links, and the feature-gated
announcement banner.

Outside Telegram every anchor keeps its native target=_blank.
This commit is contained in:
Ilia Denisov
2026-06-15 18:29:53 +02:00
parent 8e0d7f9e17
commit bd0482c376
7 changed files with 92 additions and 12 deletions
+6 -1
View File
@@ -9,6 +9,7 @@
type BannerConfig,
type BannerItem,
} from '../lib/banner';
import { onExternalLinkClick } from '../lib/telegram';
let { items = mockBanners(), config = defaultBannerConfig }: { items?: BannerItem[]; config?: BannerConfig } =
$props();
@@ -39,7 +40,11 @@
onDestroy(() => rotator?.stop());
</script>
<div class="ad" bind:this={viewport}>
<!-- The banner links are rendered via {@html}; a delegated click routes any of them through the
Telegram SDK (onExternalLinkClick uses closest('a')) so they skip the WebView confirmation. -->
<!-- svelte-ignore a11y_no_static_element_interactions -->
<!-- svelte-ignore a11y_click_events_have_key_events -->
<div class="ad" bind:this={viewport} onclick={onExternalLinkClick}>
{#key current}
<div
class="track"