Migrating from 3.x ​
This guide describes how to migrate from @tma.js/sdk 3.x to the current major version of the package. The SDK was rewritten, so most of the public API changed: availability checks, reactive values, error handling, asynchronous functions and initialization.
Changes not caught by TypeScript, meaning your code compiles but behaves differently, are marked with warning blocks. Review them carefully.
TIP
The SDK re-exports @tma.js/bridge, so changes described in the bridge migration guide apply to code importing bridge functions from @tma.js/sdk. For the overview of all packages, see Upgrading.
If you use framework bindings, also see the guides for @tma.js/sdk-react, @tma.js/sdk-solid, @tma.js/sdk-vue and @tma.js/sdk-svelte. They re-export the SDK, so this guide applies to them as well.
Overview of Breaking Changes ​
- No fp-ts. All
xFpfunctions returningEitherorTaskEitherwere replaced withsafeXfunctions returning a plain result object:{ ok: true, data }or{ ok: false, error }. Regularxfunctions still throw. - No
BetterPromise. Asynchronous functions return a regularPromise. Operations are cancelled with a standardAbortSignalpassed in thesignaloption (previouslyabortSignal). The.cancel()method andCancelledErrorare gone. - No signals. Reactive values became computed values of the
Computedtype with a singlesubscribemethod. The@tma.js/signalspackage was removed. - No
isAvailableandifAvailable. UseisSupported(), which is now a regular function, andsupports(feature). Calling an unsupported method, a method beforeinit, or a method of an unmounted component throws. - Components are singleton objects, not classes. Classes,
instanceofchecks and*Optionstypes are gone. initis required for everything. Functions that previously worked withoutinitnow throwNotInitializedError.initoptions changed.version,isInlineModeandthemeParamswere replaced withlaunchParams.
Installation ​
Update the package:
pnpm i @tma.js/sdk@latestnpm i @tma.js/sdk@latestyarn add @tma.js/sdk@latestThe package no longer depends on fp-ts, better-promises, @tma.js/signals, @tma.js/toolkit, @tma.js/transformers and @tma.js/types. If your code imported them only to work with the SDK, remove them from your dependencies:
pnpm remove fp-ts better-promises @tma.js/signals @tma.js/toolkit @tma.js/transformers @tma.js/typesThe SDK now depends on @tma.js/init-data and re-exports its types. To parse or serialize init data, install it and use its parse and serialize functions instead of parseInitDataQuery and serializeInitDataQuery.
Initialization ​
Removed Options ​
The version, isInlineMode and themeParams options were removed. Pass the complete launch parameters in the launchParams option instead:
import { init } from '@tma.js/sdk';
init({
version: '8.0',
isInlineMode: false,
themeParams: { bg_color: '#17212b' },
});import { init } from '@tma.js/sdk';
init({
launchParams: {
tgWebAppPlatform: 'tdesktop',
tgWebAppVersion: '8.0',
tgWebAppBotInline: false,
tgWebAppThemeParams: { bg_color: '#17212b' },
},
});In most cases, no options are needed: init() retrieves launch parameters itself.
postEvent Option ​
The postEvent option now accepts a throwing PostEventFn instead of PostEventFpFn.
WARNING
By default, the SDK now uses a postEvent function created with createPostEvent in the strict mode. It throws MethodUnsupportedError if the Telegram client doesn't support the method, and MethodParameterUnsupportedError if it doesn't support some of the passed parameters, like an RGB header color before Mini Apps v6.9. Previously, the default function didn't check versions.
To log a warning instead of throwing, pass your own function:
import { createPostEvent, init, retrieveLaunchParams } from '@tma.js/sdk';
const launchParams = retrieveLaunchParams();
init({
launchParams,
postEvent: createPostEvent(launchParams.tgWebAppVersion, 'non-strict'),
});initFp and isInitialized ​
initFp was replaced with safeInit, returning a result with LaunchParamsRetrieveError. The new isInitialized function returns true if the SDK is initialized.
import { initFp } from '@tma.js/sdk';
import { either as E, function as fn } from 'fp-ts';
fn.pipe(initFp(), E.match(
error => console.error(error),
cleanup => {},
));import { safeInit } from '@tma.js/sdk';
const result = safeInit();
if (!result.ok) {
console.error(result.error);
}init Is Required for Everything ​
WARNING
In 3.x, many functions checked only that the app was running inside Telegram and worked without calling init. Now all of them throw NotInitializedError until init is called:
closingBehavior: all methods;themeParams:mountandbindCssVars;mainButton: all methods exceptonClickandoffClick;miniApp:mount,close,readyandbindCssVars;viewport:mount,expandandbindCssVars;initData.restore;openLink,sendDataandshareURL.
Make sure init is called before any SDK usage. copyTextToClipboard, retrieveAndroidDeviceData, the color helpers and the bridge functions still work without it.
Other Changes ​
- Handling of the
reload_iframeandset_custom_styleevents and sendingiframe_readyare performed only when the app is launched in an iframe (Telegram Web). - Calling
initagain first performs the cleanup of the previous call.
Learn more in the Initializing section.
Component Shape ​
Components are now plain singleton objects. Classes were removed, and only TypeScript interfaces describing components are exported.
import { BackButton, backButton } from '@tma.js/sdk';
const myButton = new BackButton({ /* ... */ });
backButton instanceof BackButton; // trueimport { backButton, type BackButton } from '@tma.js/sdk';
// BackButton is an interface now. There is no way to create another
// back button instance.
const button: BackButton = backButton;As a result:
- creating components with
newis no longer possible; instanceofchecks against component classes no longer work;- all dependency injection option types were removed:
BackButtonOptions,BiometryOptions,ClosingBehaviorOptions,CloudStorageOptions,DeviceStorageOptions,HapticFeedbackOptions,InitDataOptions,InvoiceOptions,LocationManagerOptions,MainButtonOptions,MiniAppOptions,PopupOptions,QrScannerOptions,SecondaryButtonOptions,SecureStorageOptions,ServerlessOptions,SettingsButtonOptions,SwipeBehaviorOptions,ThemeParamsOptionsandViewportOptions; - all
*Fpmethods were removed. See Error Handling.
To test code using the SDK, mock the environment with mockTelegramEnv instead of creating components with custom options.
Availability Checks ​
| 3.x | Current major version |
|---|---|
fn.isAvailable(): reactive signal checking the environment, init, support and mount | Removed |
fn.ifAvailable(...args) | Removed |
x.isSupported(): reactive signal | x.isSupported(): regular function checking init and support, but not mount |
fn.supports(feature): only miniApp.setHeaderColor | miniApp.setHeaderColor, miniApp.close, mainButton.setParams, secondaryButton.setParams, openLink |
FunctionUnavailableError returned or thrown | NotInitializedError, MethodUnsupportedError, MethodParameterUnsupportedError or NotMountedError thrown |
isSupported now exists on all components depending on a Mini Apps version, including mainButton, closingBehavior, deviceStorage and secureStorage, which didn't have it, and on all functions. Methods released later than their component, like miniApp.setBottomBarColor or viewport.requestFullscreen, have their own isSupported. Learn more in the Features section.
Replacing isAvailable ​
isAvailable checked the support and the mount status at once. Check them separately:
import { backButton } from '@tma.js/sdk';
if (backButton.show.isAvailable()) {
backButton.show();
}import { backButton } from '@tma.js/sdk';
if (backButton.isSupported() && backButton.isMounted()) {
backButton.show();
}Replacing ifAvailable ​
The most common usage of ifAvailable was mounting a component and calling its methods only if it was supported. Group these calls under a single check:
import { backButton, miniApp } from '@tma.js/sdk';
backButton.mount.ifAvailable();
backButton.show.ifAvailable();
miniApp.setBottomBarColor.ifAvailable('#aabbcc');import { backButton, miniApp } from '@tma.js/sdk';
if (backButton.isSupported()) {
backButton.mount();
backButton.show();
}
if (miniApp.setBottomBarColor.isSupported() && miniApp.isMounted()) {
miniApp.setBottomBarColor('#aabbcc');
}If you used ifAvailable in many places, a small helper reproduces it:
type Checkable<A extends unknown[], R> = ((...args: A) => R) & { isSupported: () => boolean };
function ifSupported<A extends unknown[], R>(
fn: Checkable<A, R>,
...args: A
): { ok: true; data: R } | { ok: false } {
return fn.isSupported() ? { ok: true, data: fn(...args) } : { ok: false };
}
ifSupported(miniApp.setBottomBarColor, '#aabbcc');WARNING
Unlike isAvailable, isSupported doesn't check if the component is mounted. Calling a method of an unmounted component throws NotMountedError. Add isMounted() checks where the component may be unmounted.
The SDK also no longer checks if the app is running inside Telegram. Calls are blocked only by init, which fails outside Telegram unless the environment is mocked or launch parameters are passed explicitly.
Reactivity ​
Signals from @tma.js/signals were replaced with computed values. Reading a value works the same way: call it. To track changes, use the subscribe method:
| 3.x | Current major version |
|---|---|
value() | value() |
value.sub(listener) | value.subscribe(listener) |
value.sub(listener, true) (once) | Call the returned function inside the listener |
value.unsub(listener) | Call the function returned by subscribe |
value.unsubAll() | Call the functions returned by subscribe |
signal(), computed(), batch() | Removed |
Signal, SignalOptions types | Removed. The Computed type is exported from @tma.js/sdk |
import { backButton } from '@tma.js/sdk';
function listener(isVisible: boolean) {
console.log(isVisible);
}
backButton.isVisible.sub(listener);
backButton.isVisible.unsub(listener);
backButton.isVisible.sub(isVisible => {
console.log('Called once:', isVisible);
}, true);import { backButton } from '@tma.js/sdk';
const unsubscribe = backButton.isVisible.subscribe((next, prev) => {
console.log(next);
});
unsubscribe();
const unsubscribeOnce = backButton.isVisible.subscribe(isVisible => {
unsubscribeOnce();
console.log('Called once:', isVisible);
});The listener still receives the next and the previous values, is called only when the value changes, and is not called on subscribe.
The SDK no longer exports a way to create your own reactive values. If you built computed values on top of SDK signals using computed from @tma.js/signals, use a third-party reactivity library or your framework's primitives, subscribing to SDK values with subscribe.
In framework bindings, useSignal was replaced with useComputed. It accepts only computed values of the SDK:
import { backButton, useSignal } from '@tma.js/sdk-react';
const isVisible = useSignal(backButton.isVisible);import { backButton, useComputed } from '@tma.js/sdk-react';
const isVisible = useComputed(backButton.isVisible);Error Handling ​
xFp Functions ​
All xFp functions were replaced with safeX functions. Instead of Either or TaskEither, they return a result object (or a promise of it):
type Result<E, T> = { ok: false; error: E } | { ok: true; data: T };import { popup } from '@tma.js/sdk';
import { taskEither as TE, function as fn } from 'fp-ts';
await fn.pipe(
popup.showFp({ message: 'Hello!' }),
TE.match(
error => console.error(error),
buttonId => console.log(buttonId),
),
)();import { popup } from '@tma.js/sdk';
const result = await popup.safeShow({ message: 'Hello!' });
if (result.ok) {
console.log(result.data);
} else {
console.error(result.error);
}The matchError function, exported from the SDK, handles each error type separately and fails compilation if some of them are left unhandled:
import { matchError, popup } from '@tma.js/sdk';
const result = await popup.safeShow({ message: 'Hello!', timeout: 10_000 });
if (!result.ok) {
matchError(result.error, {
InvalidArgumentsError: e => console.error(e.message),
TimeoutError: e => console.error('Timed out after', e.data.timeout),
});
}The ok, err, unwrap and throwing helpers from the bridge are re-exported too.
Not every function has a safe version. Functions without expected errors, like hideKeyboard, shareStory, shareURL, switchInlineQuery and addToHomeScreen, have only the throwing version.
WARNING
Safe functions return only expected errors, like a timeout, the user's refusal or invalid arguments. Errors caused by incorrect usage or a wrong environment are always thrown, even by safe functions: NotInitializedError, NotMountedError, MethodUnsupportedError, MethodParameterUnsupportedError, ConcurrentCallError, CSSVarsBoundError and InvalidEnvError. For asynchronous functions, the returned promise is rejected.
In particular, ConcurrentCallError (opening a popup, an invoice or the QR scanner while it is already opened) and InvalidEnvError (calling a serverless endpoint without init data) were returned as errors in 3.x and are thrown now.
Promises and Cancellation ​
Asynchronous functions return a regular Promise instead of BetterPromise. The abortSignal option was renamed to signal, and the .cancel() method was removed:
import { popup } from '@tma.js/sdk';
const promise = popup.show({ message: 'Hello!', timeout: 10_000 });
promise.cancel();import { popup } from '@tma.js/sdk';
const controller = new AbortController();
const promise = popup.show({
message: 'Hello!',
timeout: 10_000,
signal: controller.signal,
});
controller.abort();When the signal is aborted, the promise is rejected with signal.reason. CancelledError was removed.
WARNING
TimeoutError is now a class of @tma.js/bridge, not of better-promises. Checks like e instanceof TimeoutError with the class imported from better-promises no longer work. Use TimeoutError.is(e) with the class imported from @tma.js/sdk. The timeout is available in e.data.timeout.
Error Classes ​
| 3.x | Current major version |
|---|---|
FunctionUnavailableError (name FunctionNotAvailableError) | Removed. Replaced with NotInitializedError, NotMountedError, MethodUnsupportedError and MethodParameterUnsupportedError |
NotAvailableError | BiometryUnavailableError |
ValidationError | InvalidResponseError. The value is in .data.value, the validation error is in cause |
ServerlessError(message, { status, type, parameters, cause }) | ServerlessError(message, { status, type, parameters }, cause) |
UnknownThemeParamsKeyError | Added .data.key |
SetEmojiStatusError, ShareMessageError, RequestChatError, FullscreenFailedError | Added .data.error. Messages got a prefix |
CancelledError | Removed. Aborted operations are rejected with signal.reason |
| — | New: NotInitializedError, NotMountedError (.data.component), InvalidColorError |
Per-function error unions were removed: OpenLinkError, OpenTelegramLinkError, ShareURLError, SendDataError, DownloadFileError, GetCurrentTimeError, HideKeyboardError, ReadTextFromClipboardError, RequestChatFnError, ShareMessageFnError, ShareStoryError, SwitchInlineQueryError, RequestPhoneAccessError and RequestWriteAccessError. The kept ones are CloudStorageError, DeviceStorageError, SecureStorageError, RequestContactError and ServerlessCallError.
All error classes have the static is method. It works even if the package is duplicated in the bundle:
import { NotMountedError } from '@tma.js/sdk';
if (NotMountedError.is(e)) {
console.error(e.data.component, 'is not mounted');
}Mounting ​
| 3.x | Current major version |
|---|---|
Asynchronous mount returned BetterPromise, mountFp returned TaskEither | mount returns Promise, safeMount returns a result with TimeoutError |
| No way to know if the component is mounting | isMounting computed value (viewport, biometry, locationManager) |
viewport had no unmount | viewport.unmount() |
Calling a method of an unmounted component returned FunctionUnavailableError | Throws NotMountedError |
WARNING
Behavior changes:
- The state saved before the page reload is restored only on the first mount after the reload. Previously, it was restored on every mount.
- Calling
unmountwhile an asynchronous mount is in progress cancels it. Previously, the component got mounted when the request completed. - The component state is saved in
sessionStorageunder thetma.js/sdk/<component>keys instead oftapps/<component>. The state saved by 3.x is not restored after the update. This matters only if the page is reloaded within the same session during the update rollout. miniApp.mount()mountsthemeParamstoo, if it is not mounted yet.
Component Changes ​
Buttons ​
Changes in backButton, settingsButton, mainButton and secondaryButton:
onClick(listener, once?)becameonClick(listener, { once?, signal? }).offClick(listener, once?)becameoffClick(listener).onClickandoffClicknever throw and don't requireinit.- All
*Fpmethods were removed.
import { backButton } from '@tma.js/sdk';
backButton.onClick(listener, true);
backButton.offClick(listener, true);import { backButton } from '@tma.js/sdk';
backButton.onClick(listener, { once: true });
backButton.offClick(listener);Main and Secondary Buttons ​
- Both buttons are described by the shared
BottomButton<S>interface. Their state types areMainButtonStateandSecondaryButtonState. mainButton.isSupported()was added.setParams.supports('hasShineEffect' | 'iconCustomEmojiId')was added.enableShineEffect,disableShineEffectandsetIconCustomEmojiIdhave their ownisSupportedmethod.iconCustomEmojiId()returnsstring | undefined. Previously, it returned''when not set.
WARNING
- Parameters that were not set, like the colors or the custom emoji identifier, are no longer sent to the Telegram client. Previously, an empty
icon_custom_emoji_idwas always sent. - Passing
iconCustomEmojiIdbefore Mini Apps v9.5 throwsMethodParameterUnsupportedErrorwith the defaultpostEvent. - The default
secondaryButton.bgColor()is nowminiApp.bottomBarColorRgb(), thenthemeParams.secondaryBgColor(), then#ffffff. Previously, it fell back to#000000.
Closing Behavior and Swipe Behavior ​
closingBehavior.isSupported()was added.*Fpmethods were removed.
Mini App ​
- New methods:
safeSetBgColor,safeSetBottomBarColorandsafeSetHeaderColorreturningUnknownThemeParamsKeyError. setBgColor,setBottomBarColorandsetHeaderColorhave their ownisSupportedmethod.close.supports('returnBack')was added.- Colors are parsed with
toRGB, so the#RGB,#RGBA,#RRGGBBAA,rgb()andrgba()formats are accepted and converted to#RRGGBB. - The
MiniAppGetCssVarNameFntype was removed. TheAnyColortype is exported.
WARNING
- Before mounting,
isActive()returnstrue. Previously, it returnedfalse. - After mounting,
headerColor()is'bg_color', as in the official SDK. Previously, it was'header_bg_color'. - The bottom bar color with the default
bottom_bar_bg_colorkey falls back to thesecondary_bg_colortheme color, like in the official SDK. isDark()returnsfalseif the background color is unknown or invalid.close(false)sends empty parameters instead of{ return_back: false }.
Theme Params ​
- The component interface is now called
ThemeParamsComponent. TheThemeParamsname refers to the theme parameters data type. See Type Renames. - The
ThemeParamsStateandThemeParamsGetCssVarNameFntypes were removed. UseThemeParams. - Unbinding CSS variables now removes them. Previously, they stayed set.
WARNING
isDark()returnsfalseif the theme has nobg_color. Previously, it returnedtrue.- The
theme_changedevent replaces the whole state. Previously, new values were merged with the old ones, so colors missing in the new theme kept their old values.
Viewport ​
isStablewas removed. Useviewport.height() === viewport.stableHeight().safeAreaInsetTop,safeAreaInsetBottom,safeAreaInsetLeft,safeAreaInsetRightand the samecontentSafeAreaInset*values were removed. UsesafeAreaInsets()andcontentSafeAreaInsets(). The related CSS variables are still created bybindCssVars.- New:
safeMount,isMounting,unmount,safeRequestFullscreenandsafeExitFullscreen. requestFullscreenandexitFullscreenhave their ownisSupportedmethod.
import { viewport } from '@tma.js/sdk';
viewport.safeAreaInsetTop();
viewport.isStable();import { viewport } from '@tma.js/sdk';
viewport.safeAreaInsets().top;
viewport.height() === viewport.stableHeight();WARNING
viewport.bindCssVars() now throws NotMountedError if the component is not mounted.
Init Data ​
- The component interface is now called
InitDataComponent. TheInitDataname refers to the init data type. See Type Renames. restoreFpwas replaced withsafeRestore, returningInvalidInitDataErrorif init data is invalid.- Init data is parsed with @tma.js/init-data. Unknown keys are removed,
signatureis optional.
WARNING
initData.restore() now reads init data from the launch parameters passed to (or retrieved by) init. Previously, it retrieved launch parameters itself and worked without init.
Haptic Feedback ​
impactOccurredFp,notificationOccurredFpandselectionChangedFpwere removed.isSupportedbecame a regular function.
Biometry ​
state().tokenwas removed. The token is returned only byauthenticate.NotAvailableErrorwas replaced withBiometryUnavailableError.- New:
safeMount,isMounting,safeAuthenticate,safeRequestAccessandsafeUpdateToken. BiometryAuthenticateOptionsandBiometryRequestAccessOptionswere replaced withBiometryReasonOptions.BiometryAuthenticateResultwas added.reasonandtokenno longer acceptnull.updateTokenupdatesstate().tokenSaved.
WARNING
requestAccess()resolves withtrueif the access was granted. In 3.x, it mistakenly resolved with theaccessRequestedvalue.- Calling
authenticate,requestAccessorupdateTokenwhile another of these requests is in progress throwsConcurrentCallError.
Location Manager ​
LocationManagerRequestLocationResponsewas renamed toLocationData.- New:
safeMount,isMountingandsafeRequestLocation. - After mounting, the state is updated on each
location_checkedevent.
Popup ​
ShowOptionswas renamed toPopupShowOptions,ShowOptionsButtontoPopupShowButton.showFpwas replaced withsafeShow, returningInvalidArgumentsErrororTimeoutError.- The
preparePopupParamsfunction validating popup parameters is exported.
Invoice ​
openSlugFpandopenUrlFpwere replaced withsafeOpenSlugandsafeOpenUrl.- An invalid URL passed to
openUrlresults inInvalidArgumentsError. Previously, aTypeErrorwas thrown.
QR Scanner ​
openFpandcaptureFpwere replaced withsafeOpenandsafeCapture.- The
captureoption ofcapturebecame optional. By default, the first scanned QR code is captured, soqrScanner.capture()can be called without arguments. - The
QrScannerOpenOptionsandQrScannerCaptureOptionstypes are exported.
WARNING
When the timeout is reached or the operation is aborted, the scanner is closed. Previously, it stayed opened.
Cloud Storage ​
- The
getItem(keys[])overload was removed. UsegetItems. *Fpmethods were replaced withsafe*methods returningCloudStorageError.- Methods accept
{ timeout?, signal? }options.
const values = await cloudStorage.getItem(['a', 'b']);const values = await cloudStorage.getItems(['a', 'b']);Device Storage and Secure Storage ​
isSupported()was added.- Methods accept
{ timeout?, signal? }options as the last argument. *Fpmethods were replaced withsafe*methods. Errors areDeviceStorageMethodError | TimeoutErrorandSecureStorageMethodError | TimeoutError.- The
SecureStorageItemtype describing thesecureStorage.getItemresult is exported.
Serverless ​
callFpwas replaced withsafeCall.- The
abortSignaloption was renamed tosignal. ServerlessCallErrorno longer includesInvalidEnvError.
WARNING
If the launch parameters have no init data, call and safeCall throw InvalidEnvError. Previously, callFp returned it as an error.
Function Changes ​
All xFp functions were replaced with safeX functions, and every function got the isSupported method:
| 3.x | Current major version |
|---|---|
addToHomeScreenFp | Removed, use addToHomeScreen |
checkHomeScreenStatusFp | safeCheckHomeScreenStatus |
downloadFileFp | safeDownloadFile |
getCurrentTimeFp | safeGetCurrentTime |
hideKeyboardFp | Removed, use hideKeyboard |
openLinkFp | safeOpenLink |
openTelegramLinkFp | safeOpenTelegramLink |
readTextFromClipboardFp | safeReadTextFromClipboard |
requestChatFp | safeRequestChat |
requestContactFp | safeRequestContact |
requestContactCompleteFp | safeRequestContactComplete |
requestEmojiStatusAccessFp | safeRequestEmojiStatusAccess |
requestPhoneAccessFp | safeRequestPhoneAccess |
requestWriteAccessFp | safeRequestWriteAccess |
sendDataFp | safeSendData |
setEmojiStatusFp | safeSetEmojiStatus |
shareMessageFp | safeShareMessage |
shareStoryFp | Removed, use shareStory |
shareURLFp | Removed, use shareURL |
switchInlineQueryFp | Removed, use switchInlineQuery |
Other changes:
openLink.supports('tryInstantView' | 'tryBrowser')was added.switchInlineQuerythrowsInvalidEnvErrorif the app was not launched in inline mode, and itsisSupportedreturnsfalsein this case. The inline mode is taken from thetgWebAppBotInlinelaunch parameter.requestContactandrequestContactComplete: theRequestedContactCompleteDatatype was renamed toRequestedContactComplete, the timeout now applies to the whole operation, and responses of Telegram for macOS are handled correctly.getCurrentTimereturnsInvalidResponseErrorinstead ofValidationError.- New exports:
isTelegramHostnameandpreparePopupParams.
Colors ​
| 3.x | Current major version |
|---|---|
isColorDark, isColorDarkFp | isColorDark, safeIsColorDark |
toRGB, toRGBFp | toRGB, safeToRGB, error InvalidColorError |
isRGB | isRGB |
toRGBFull, toRGBFullFp | Removed |
isRGBShort, isRGBA, isRGBAShort, isAnyRGB | Removed |
toRGB accepts the #RGB, #RGBA, #RRGGBB, #RRGGBBAA, rgb() and rgba() formats and always returns #RRGGBB: the alpha channel is dropped. There is no conversion to #RRGGBBAA anymore.
Type Renames ​
Some names now mean something different:
| Name | 3.x | Current major version |
|---|---|---|
InitData | Component class | Init data type. The component interface is InitDataComponent |
ThemeParams | Component class | Theme parameters type. The component interface is ThemeParamsComponent |
TimeoutError | Class of better-promises | Class of @tma.js/bridge |
isSupported | Reactive signal | Regular function |
import type { InitDataType, ThemeParamsType } from '@tma.js/sdk';import type { InitData, ThemeParams } from '@tma.js/sdk';Other type changes:
| 3.x | Current major version |
|---|---|
InitDataType | InitData |
ThemeParamsType, ThemeParamsState | ThemeParams |
AsyncOptions ({ abortSignal?, timeout? }) | AsyncOptions ({ signal?, timeout? }) |
LocationManagerRequestLocationResponse | LocationData |
ShowOptions, ShowOptionsButton | PopupShowOptions, PopupShowButton |
BiometryAuthenticateOptions, BiometryRequestAccessOptions | BiometryReasonOptions |
RequestedContactCompleteData | RequestedContactComplete |
RetrieveLaunchParamsResult | LaunchParams |
KnownThemeParamsKey | Removed |
MiniAppGetCssVarNameFn, ThemeParamsGetCssVarNameFn | Removed |
New types: Computed, IsSupported, Supports, WithIsSupported, WithSupports, StatefulComponent, MountableComponent, ButtonComponent, BottomButton, BottomButtonState, BottomButtonFeature, AnyColor, ViewportCSSVarKey, BiometryAuthenticateResult, CloudStorageError, SecureStorageItem, QrScannerOpenOptions and QrScannerCaptureOptions.
WARNING
The tgWebAppData launch parameter is now the raw init data string, not a parsed object. Use the initData component or the parse function of @tma.js/init-data to get the parsed value.
Bridge Re-exports ​
The SDK now re-exports everything from @tma.js/bridge. Notable changes of the re-exported API:
onandoffwere renamed toonEventandoffEvent. Listening to all events is done withonAnyEventandoffAnyEvent.retrieve*Fp,requestFp,invokeCustomMethodFpand other*Fpfunctions were replaced withsafe*functions.request2was renamed torequest.debug,targetOriginandloggersignals were replaced withisDebug,getTargetOriginandgetLoggerfunctions.isTMA('complete')was replaced withisTMAAsync.mockTelegramEnvaccepts theonMethodoption instead ofonEvent.parseLaunchParamsQueryandserializeLaunchParamsQuerywere replaced withparseLaunchParamsandserializeLaunchParams.applyPolyfills,createLogger,deepSnakeToCamelObjKeysandCancelledErrorwere removed.
WARNING
In 3.x, the SDK exported its own postEvent, request, request2 and invokeCustomMethod wrappers using the postEvent function configured in init. Now these names are re-exported from the bridge directly and don't use the postEvent passed to init, so they don't check if methods are supported. Pass the function explicitly if needed:
import { createPostEvent, request, retrieveLaunchParams } from '@tma.js/sdk';
const postEvent = createPostEvent(retrieveLaunchParams().tgWebAppVersion);
await request('web_app_request_phone', 'phone_requested', { postEvent });Also, request called with an array of events now always resolves with { event, payload }, like request2 did. Previously, request resolved with the payload only.
Learn more in the bridge migration guide.
