Skills Agentes

Expo App Clip

Framework (código abierto). Añade un target de App Clip para iOS a una app Expo, invocado desde una URL vía AASA junto a la app principal.

Oficial
Estrellas
2.6k

en todo el repo

Actividad
58

0–100, la ruta de este skill

Actualizado
hace 2 meses

último commit aquí

Commits
3

últimos 90 días

Contexto
2.4k tok

61 tok en reposo

Paquete
3 archivos

12 KB

Instalar

Funciona con cualquier agente que lea SKILL.md

npx -y skills add expo/skills --skill expo-app-clip --agent claude-code

Se instala solo en este repositorio.

Este skill makes network requests.

Qué hace

  • Añade un target de iOS App Clip en `targets/clip/` dentro del proyecto Expo
  • Configura entitlements, deriva el bundle ID como `<parent>.clip` y genera archivos de configuración
  • Genera y sirve el archivo AASA (`apple-app-site-association`) con bloque `appclips`
  • Añade la etiqueta meta Smart App Banner en `+html.tsx`
  • Configura y sube el build a TestFlight con ambos targets (parent y Clip)

Úsalo cuando

  • El usuario menciona App Clip, AASA, apple-app-site-association, appclips o smart app banner
  • Se quiere lanzar un Clip ligero de iOS invocado desde una URL junto a la app principal

No lo uses cuando

    Qué lo activa

    Di cualquiera de estas frases y el agente debería cargar este skill.

    • “Quiero añadir un App Clip a mi app de Expo”
    • “Cómo configuro el archivo apple-app-site-association para mi Clip”
    • “Necesito un smart app banner y un App Clip invocado desde una URL”

    SKILL.md

    En inglés

    Add an App Clip to an Expo App

    Requirements. Adding the App Clip target is open source. Shipping one requires an Apple Developer Program membership and App Store review, and the AASA file must be served over HTTPS on your domain (any HTTPS host works; EAS Hosting is one option). Building via EAS Build or bunx testflight uses your EAS plan's build minutes. See https://expo.dev/pricing and https://developer.apple.com/app-clips/.

    Adds an iOS App Clip target to an Expo project. The Clip lives in targets/clip/, ships alongside the parent app, and is invoked from a URL on the app's domain via an Apple App Site Association (AASA) file.

    The parent app's bundle ID becomes com.<username>.<app-name> and the Clip's is automatically derived as <parent>.clip (e.g. com.bacon.may20.clip).

    1. Set bundleIdentifier and appleTeamId

    bun create target warns if these are missing. Add to app.json:

    {
      "expo": {
        "ios": {
          "bundleIdentifier": "com.<username>.<app-name>",
          "appleTeamId": "XX57RJ5UTD"
        }
      }
    }
    

    2. Add the App Clip target

    bun create target clip
    

    This installs @bacons/apple-targets, adds it to the plugins array in app.json, and writes:

    • targets/clip/expo-target.config.js — the target's config plugin
    • targets/clip/Info.plist — Clip Info.plist
    • targets/clip/AppDelegate.swift, Assets.xcassets, etc.

    Pick a good icon or reuse the existing one defined in the app — check it with bunx expo config under the icon or ios.icon key.

    3. Wire up associated domains

    The parent app and the Clip each need the Associated Domains entitlement pointing at the domain that hosts the AASA file.

    In app.json, add both applinks: (parent) and appclips: (Clip invocation) entries:

    {
      "expo": {
        "ios": {
          "associatedDomains": [
            "applinks:may20.expo.app",
            "appclips:may20.expo.app"
          ]
        }
      }
    }
    

    In targets/clip/expo-target.config.js, declare the Clip's entitlement:

    /** @type {import('@bacons/apple-targets/app.plugin').ConfigFunction} */
    module.exports = (config) => ({
      type: "clip",
      icon: "https://github.com/expo.png",
      entitlements: {
        "com.apple.developer.associated-domains": ["appclips:may20.expo.app"],
      },
    });
    

    If you skip this, expo prebuild will print: Apple App Clip may require the associated domains entitlement but none were found.

    4. Register bundle IDs and create the App Store entry

    bunx setup-safari
    

    This logs in to the Apple Developer account, registers com.bacon.may20, creates the App Store Connect entry, and prints:

    • A starter apple-app-site-association JSON
    • A <meta name="apple-itunes-app"> tag with the iTunes app id
    • Team ID, iTunes ID, and Bundle ID

    5. Host the AASA file

    App Clips are invoked when iOS fetches https://<your-domain>/.well-known/apple-app-site-association and finds a matching appclips entry.

    mkdir -p public/.well-known
    touch public/.well-known/apple-app-site-association
    

    Paste the JSON setup-safari printed, but add an appclips block for the Clip's full app ID (<TeamID>.<ClipBundleID>). The output of setup-safari only covers the parent app:

    {
      "applinks": {
        "details": [
          {
            "appIDs": ["XX57RJ5UTD.com.bacon.may20"],
            "components": [{ "/": "*", "comment": "Matches all routes" }]
          }
        ]
      },
      "appclips": {
        "apps": ["XX57RJ5UTD.com.bacon.may20.clip"]
      },
      "activitycontinuation": {
        "apps": ["XX57RJ5UTD.com.bacon.may20"]
      },
      "webcredentials": {
        "apps": ["XX57RJ5UTD.com.bacon.may20"]
      }
    }
    

    Notes:

    • The file has no extension and no Content-Type requirements beyond being served as-is. Expo Router static export serves files in public/ verbatim.
    • The appclips block is what lets a URL on the domain launch the Clip.
    • webcredentials is used for sharing credentials between the website, parent app, and the App Clip.
    • activitycontinuation is optional and used for sharing the link between mobile and desktop. Must be used with Head from expo-router — see https://docs.expo.dev/router/advanced/apple-handoff/
    • Notation and route-disabling details: https://sosumi.ai/documentation/xcode/supporting-associated-domains

    6. Add the Smart App Banner meta tag

    Create src/app/+html.tsx (Expo Router's HTML shell) and add the tag from setup-safari. Create the versioned template if it doesn't exist:

    bunx expo customize src/app/+html.tsx
    

    Add the meta tag to the <head>:

    import { ScrollViewStyleReset } from "expo-router/html";
    
    export default function Root({ children }: { children: React.ReactNode }) {
      return (
        <html lang="en">
          <head>
            <meta charSet="utf-8" />
            <meta httpEquiv="X-UA-Compatible" content="IE=edge" />
            <meta name="viewport" content="width=device-width, initial-scale=1" />
            <meta name="apple-itunes-app" content="app-id=6771566491" />
            <ScrollViewStyleReset />
          </head>
          <body>{children}</body>
        </html>
      );
    }
    

    To make the website show the App Clip card instead of the install card, use:

    <meta
      name="apple-itunes-app"
      content="app-id=6771566491, app-clip-bundle-id=com.bacon.may20.clip, app-clip-display=card"
    />
    

    7. Deploy the website

    The AASA file must be live before iOS will trust the association. Use EAS Hosting:

    bunx expo export -p web
    eas deploy --prod
    

    This publishes the site (including /.well-known/apple-app-site-association) at https://<slug>.expo.app. Verify:

    curl https://may20.expo.app/.well-known/apple-app-site-association
    

    8. Mirror permissions

    Inspect the parent app's permissions after prebuild:

    npx expo config --type introspect
    

    Look at the infoPlist object — mirror the permission keys in the App Clip's Info.plist so matching APIs can be used from the Clip.

    Set deploymentTarget: "17.6" in the Clip's target config — App Clips have a higher minimum size limit in iOS 17.6.

    If the app uses push notifications or location services, add to the App Clip's Info.plist to request the necessary permissions:

    <key>NSAppClip</key>
    <dict>
      <key>NSAppClipRequestEphemeralUserNotification</key>
      <false/>
      <key>NSAppClipRequestLocationConfirmation</key>
      <true/>
    </dict>
    

    9. Build and submit to TestFlight

    bunx testflight
    

    This will:

    1. Generate an eas.json if missing.
    2. Set up credentials for both targets (parent + Clip). Each gets its own provisioning profile but can share a single Distribution Certificate.
    3. Sync capabilities — note Enabled: Associated Domains for the Clip target.
    4. Build, upload, and schedule a TestFlight submission.

    10. Configure App Clip metadata

    Pull existing App Store metadata to local:

    eas metadata:pull
    

    Add apple.appClip to store.config.json. Up to 3 invocation URLs can launch the Clip from a web page:

    {
      "configVersion": 0,
      "apple": {
        "appClip": {
          "defaultExperience": {
            "action": "PLAY",
            "releaseWithAppStoreVersion": true,
            "reviewDetail": {
              "invocationUrls": ["https://may20.expo.app/", null, null]
            },
            "info": {
              "en-US": {
                "subtitle": "Instantly native with Expo",
                "headerImage": "store/apple/app-clip/en-US/asc-app-clip.png"
              }
            }
          }
        }
      }
    }
    

    The headerImage must be a 1800x1200 PNG with no opacity.

    Push back to the store:

    eas metadata:push
    

    Apple's recommended App Clip metadata guidelines: https://sosumi.ai/documentation/appclip/configuring-the-launch-experience-of-your-app-clip

    What you get

    • Parent app target: com.bacon.may20
    • App Clip target: com.bacon.may20.clip, lives in targets/clip/
    • AASA hosted at https://may20.expo.app/.well-known/apple-app-site-association
    • Smart App Banner meta tag on every web route
    • Every route linked to its native counterpart
    • TestFlight build of the parent app with the Clip embedded

    Once Apple invokes the Clip from a URL on the domain, iOS opens targets/clip/'s entry point which loads the React Native app.

    Native detection (optional)

    To let JS detect when it's running inside an App Clip and present an install prompt for the full app, create a local Expo module (bunx create-expo-module --local) that exposes navigator.appClip.prompt().

    See ./references/native-module.md for the Swift module, TypeScript interface, and usage.

    References

    • ./references/native-module.md — Local Expo module to detect App Clip context and present the SKOverlay install prompt

    Submitting Feedback

    If you encounter errors, misleading or outdated information in this skill, report it so Expo can improve:

    npx --yes submit-expo-feedback@latest --category skills --subject "expo-app-clip" "<actionable feedback>"
    

    Only submit when you have something specific and actionable to report. Include as much relevant context as possible. If an AI agent repeatedly failed or the user had to take over an Expo task, load the expo-skill-feedback skill and follow its eval-candidate flow instead of reusing the command above.

    Reproducido de expo/skills bajo licencia MIT. Leer esta página en markdown.

    Archivos

    3 archivos en el paquete. Solo se lee SKILL.md al activarse — las referencias se cargan si el skill decide que las necesita.

    Antes de instalar

    Requiere membresía de Apple Developer Program, revisión de App Store, y servir el archivo AASA vía HTTPS en el dominio propio.

    Necesita en el PATH:buncurlnpx

    Detalles

    Creador
    expo
    Licencia
    MIT
    Recursos incluidos
    referencias
    Repositorio
    expo/skills
    Código fuente
    Ver SKILL.md

    Más de expo/skills

    Este repo incluye 27 skills. Si instalas uno, normalmente ya tienes los demás. Ver el pack skills entero y su comando de instalación

    Servicio de pago de EAS para ejecutar y controlar la app de un usuario en un simulador remoto de iOS/Android alojado en la nube de EAS, incluso desde agentes de IA.

    Costo de contexto al activarse
    5.7k tok
    Tamaño del paquete
    5 archivos
    Última actualización
    el mes pasado
    Oficialherramientas desarrollo

    Framework (OSS). Pautas para actualizar versiones del SDK de Expo y resolver problemas de dependencias.

    Costo de contexto al activarse
    1.9k tok
    Tamaño del paquete
    9 archivos
    Última actualización
    el mes pasado
    Oficialherramientas desarrollo

    Repositorio oficial expo/examples con ~70 integraciones `with-*` (Stripe, Clerk, Supabase, OpenAI, mapas, Reanimated, SQLite, Skia, NativeWind, etc.) para adaptar o scaffoldear proyectos.

    Costo de contexto al activarse
    1.7k tok
    Tamaño del paquete
    3 archivos
    Última actualización
    el mes pasado
    Oficialherramientas desarrollo

    Framework (OSS) para construir UI nativa con el paquete @expo/ui: SwiftUI real en iOS y Jetpack Compose en Android, en vez de Reanimated o librerías de UI de la comunidad RN.

    Costo de contexto al activarse
    1.7k tok
    Tamaño del paquete
    7 archivos
    Última actualización
    el mes pasado
    Oficialdesarrollo apis

    Framework (OSS). Migra una app web React existente a una app nativa iOS/Android con Expo, screen por screen, usando expo-dom para el mecanismo de shell.

    Costo de contexto al activarse
    2.6k tok
    Tamaño del paquete
    6 archivos
    Última actualización
    el mes pasado
    Oficialdesarrollo apis

    Framework (OSS). Punto de entrada y enrutador para toda tarea de Expo o EAS: detecta el objetivo real, dirige a la skill expo-* / eas-* correcta y aplica las reglas de configuración compartidas.

    Costo de contexto al activarse
    2.2k tok
    Tamaño del paquete
    2 archivos
    Última actualización
    el mes pasado
    Oficialherramientas desarrollo

    Skills relacionados

    Úsalo cuando la implementación esté completa, todos los tests pasen, y necesites decidir cómo integrar el trabajo.

    Costo de contexto al activarse
    1.9k tok
    Tamaño del paquete
    1 archivo
    Última actualización
    el mes pasado
    herramientas desarrollo

    Úsalo al empezar trabajo de feature que necesita aislamiento del workspace actual, o antes de ejecutar planes de implementación: asegura un workspace aislado vía herramientas nativas o fallback a git worktree.

    Costo de contexto al activarse
    1.7k tok
    Tamaño del paquete
    1 archivo
    Última actualización
    hace 3 meses
    herramientas desarrollo

    Úsala al crear nuevas skills, editar skills existentes o verificar que funcionan antes de desplegarlas.

    Costo de contexto al activarse
    6.6k tok
    Tamaño del paquete
    7 archivos
    Última actualización
    el mes pasado
    herramientas desarrollo