AbsoluteJS

Branding & Deep Links

One PNG becomes every icon and launch screen on iOS and Android, and links to your site open the right screen in your app. Both are configured in absolute.config.ts; you never edit an asset catalog or an intent filter.

#Icons and splash

Only icon is required. Each optional field refines one platform, and anything you leave out is made from the icon. Paths are relative to the project, and each file can be up to 32 MiB.

TS
import { defineConfig } from '@absolutejs/absolute';

export default defineConfig({
  mobile: {
    appId: 'com.example.shop',
    appName: 'Shop',
    server: { productionOrigin: 'https://shop.example.com' },
    branding: {
      icon: 'assets/mobile/icon.png',
      android: {
        backgroundColor: '#0B1020',
        foreground: 'assets/mobile/android-foreground.png',
        monochrome: 'assets/mobile/android-monochrome.png'
      },
      ios: {
        darkIcon: 'assets/mobile/ios-dark.png',
        tintedIcon: 'assets/mobile/ios-tinted.png'
      },
      splash: {
        backgroundColor: '#FFFFFF',
        darkBackgroundColor: '#0B1020',
        logoScale: 0.25
      }
    }
  }
});
branding.What it isFormat
iconRequired. The app icon on iOS and older Android launchersSquare PNG, at least 1024×1024
android.foregroundAdaptive-icon artwork; keep it inside Android’s safe zoneTransparent PNG, 1024×1024
android.backgroundColorAdaptive-icon background color#RRGGBB, default #FFFFFF
android.backgroundImageAdaptive-icon background image, in place of a colorOpaque PNG, 1024×1024
android.monochromeTurns on Android themed iconsTransparent PNG, 1024×1024
ios.darkIconThe iOS dark-appearance iconPNG, 1024×1024
ios.tintedIconThe iOS tinted-appearance iconPNG, 1024×1024
splash.backgroundColorLaunch screen background, light mode#RRGGBB, default #FFFFFF
splash.darkBackgroundColorLaunch screen background, dark mode#RRGGBB, default #111111
splash.logoScaleSize of the centered icon on the launch screen0.1 to 0.4, default 0.2
splash.imageA finished launch image, used instead of the centered iconSquare PNG, at least 2732×2732 (also splash.darkImage)

#Generate

mobile assets produces every size each platform needs, including Android’s monochrome icon and iOS’s dark and tinted icons. mobile sync runs it for you whenever the artwork or config changes.

BASH
bunx absolute mobile assets --preview --yes   # generate, plus a preview page
bunx absolute mobile assets --check           # fail if anything is stale
bunx absolute mobile assets android --yes     # one platform only
--previewAlso writes .absolutejs/mobile/branding/preview.html, showing the icon in each launcher mask and the launch screens.
--checkFails if any platform in mobile.platforms is out of date with your artwork. Good for CI.
--yesInstalls the pinned icon generator without asking, on the first run.
--jsonPrints the status as JSON for scripts.
Edit the source, not the output
Commit your source artwork and the generated native files, but change only the artwork and config: rerun mobile assets instead of editing Android launcher resources or the iOS AppIcon.appiconset by hand. The release check warns when branding is missing and fails when it is invalid or out of date.

A link to https://shop.example.com/orders/42 opens the app on the same page your site shows at /orders/42, whether the app was closed or already running. Universal links on iOS and app links on Android are the HTTPS kind; a custom scheme is the shorter fallback. In a custom-scheme link the word right after shop:// is ignored and the path follows it, so shop://open/orders/42 opens /orders/42; so does shop:///orders/42.

FeatureHTTPS linksCustom scheme
Examplehttps://shop.example.com/orders/42shop://open/orders/42
Opens the app from a browser, email or message
Falls back to your website without the app
Proves you own the domain
Configured bydeepLinks.hosts and your serverdeepLinks.scheme
TS
import { defineConfig } from '@absolutejs/absolute';

export default defineConfig({
  mobile: {
    appId: 'com.example.shop',
    appName: 'Shop',
    server: { productionOrigin: 'https://shop.example.com' },
    deepLinks: {
      scheme: 'shop',
      hosts: ['links.example.com'],
      apple: { appIdPrefix: 'ABCDE12345' },
      android: {
        sha256CertificateFingerprints: [
          '14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5'
        ]
      }
    }
  }
});
deepLinks.Meaning
schemeThe custom URL scheme. Defaults to your appId in lowercase.
hostsExtra domains that open the app. Your productionOrigin host is always included. Hostnames only: no ports, wildcards or paths.
apple.appIdPrefixYour Apple Team ID, ten letters or digits. Required in production when iOS is a platform.
android.sha256CertificateFingerprintsThe SHA-256 fingerprint of every certificate that signs a build people install. Required in production when Android is a platform.

mobile sync writes these into the native projects: Android intent filters with automatic verification, and the iOS URL scheme and associated domains entitlement. Links that carry a username or password are refused. The sign-in callback uses the same scheme and is handled by Auth, not your pages.

#Team ID and fingerprints

1
Apple Team ID
Sign in to developer.apple.com and open Account → Membership details. The Team ID is your appIdPrefix.
2
Your Android signing key
Read the SHA-256 fingerprint of the key you sign releases with from its keystore.
keytool -list -v -keystore release.keystore -alias upload | grep SHA256
3
Google Play’s signing key
If Google Play signs your app, also add the app signing key’s SHA-256 from the App integrity page in Play Console. People who install from Play get builds signed with that key.

Fingerprints can be written with or without colons and in any case.

#Association files

Apple and Google check that you own a domain by fetching a file from it. Your AbsoluteJS server serves both, built from your config, with no route to write:

PathForContains
/.well-known/apple-app-site-associationiOS universal linksYour Team ID and appId, matching every path
/.well-known/assetlinks.jsonAndroid app linksYour appId and certificate fingerprints
JSON
{
  "applinks": {
    "details": [
      {
        "appIDs": ["ABCDE12345.com.example.shop"],
        "components": [{ "/": "/*" }]
      }
    ]
  }
}
Required before production
A production server will not start without deepLinks.apple.appIdPrefix when mobile.platforms includes iOS, or without deepLinks.android.sha256CertificateFingerprints when it includes Android, so a release never ships with links that silently open the browser. Development works without them.

Every domain in hosts must serve the same files. If another server hosts one of them, write the files out and deploy them there. Once deployed, --verify fetches each host’s files and checks they match exactly, with no redirects.

BASH
bunx absolute mobile associations             # write both files to .absolutejs/mobile/associations
bunx absolute mobile associations --verify    # fetch them from every host and compare

Routing needs no code: the page for the link’s path opens by itself. To react to the link as well, such as recording where a visit came from, use links from @absolutejs/devices. It works the same on the web, where the launch link is the page’s own URL.

TS
import { links } from '@absolutejs/devices';

const launch = await links.getLaunchLink();
const referral = launch?.query.get('ref');
if (referral) recordReferral(referral);

const stopListening = await links.onOpenLink((link) => {
  if (link.pathname.startsWith('/invite/')) showInviteBanner();
});

await links.openExternal('https://status.example.com');
await stopListening();

openExternal opens http and https links in the system browser in the app; on the web it also allows mailto: and tel:.