SnippetIntent PRO
Requires Scripting PRO
SnippetIntent is a special kind of AppIntent whose purpose is to render interactive Snippet UI cards inside the Shortcuts app (iOS 26+).
Key characteristics:
- Must be registered in
app_intents.tsx
- Must specify
protocol: AppIntentProtocol.SnippetIntent
perform() must return a VirtualNode (TSX UI)
- Must be returned via
Intent.snippetIntent()
- Must be invoked from the Shortcuts action “Show Snippet Intent”
- SnippetIntent is ideal for building interactive, step-based UI inside a Shortcut
It is not a data-returning Intent; it is exclusively for UI rendering in Shortcuts.
2. System Requirements
SnippetIntent requires iOS 26 or later.
On iOS versions earlier than 26:
Intent.snippetIntent() is not available
Intent.requestConfirmation() cannot be used
- The Shortcuts action “Show Snippet Intent” does not exist
- SnippetIntent-type AppIntents cannot be invoked by Shortcuts
3. Registering a SnippetIntent (app_intents.tsx)
Example:
1export const PickColorIntent = AppIntentManager.register<void>({
2 name: "PickColorIntent",
3 protocol: AppIntentProtocol.SnippetIntent,
4 perform: async () => {
5 return <PickColorView />
6 }
7})
Another SnippetIntent:
1export const ShowResultIntent = AppIntentManager.register({
2 name: "ShowResultIntent",
3 protocol: AppIntentProtocol.SnippetIntent,
4 perform: async ({ content }: { content: string }) => {
5 return <ResultView content={content} />
6 }
7})
Requirements:
protocol must be AppIntentProtocol.SnippetIntent
perform() must return a TSX UI (VirtualNode)
- SnippetIntent cannot return non-UI types such as text, numbers, JSON, or file paths
4. Wrapping SnippetIntent Return Values — Intent.snippetIntent
A SnippetIntent cannot be passed directly to Script.exit().
It must be wrapped in a IntentSnippetIntentValue.
1const snippetValue = Intent.snippetIntent(
2 ShowResultIntent({ content: "Example Text" })
3)
4
5Script.exit(snippetValue)
Type Definition
1type SnippetIntentValue = {
2 value?: IntentAttributedTextValue | IntentFileURLValue | IntentJsonValue | IntentTextValue | IntentURLValue | IntentFileValue | null
3 snippetIntent: AppIntent<any, VirtualNode, AppIntentProtocol.SnippetIntent>
4}
5
6declare class IntentSnippetIntentValue extends IntentValue<
7 'SnippetIntent',
8 SnippetIntentValue
9> {
10 value: SnippetIntentValue
11 type: 'SnippetIntent'
12}
This wrapper makes the return value compatible with the Shortcuts “Show Snippet Intent” action.
5. Snippet Confirmation UI — Intent.requestConfirmation
iOS 26 Snippet Framework provides built-in confirmation UI driven by SnippetIntent.
API
1Intent.requestConfirmation(
2 actionName: ConfirmationActionName,
3 intent: AppIntent<any, VirtualNode, AppIntentProtocol.SnippetIntent>,
4 options?: {
5 dialog?: Dialog;
6 showDialogAsPrompt?: boolean;
7 }
8): Promise<void>
ConfirmationActionName
A predefined list of semantic action names used by system UI:
"add" | "addData" | "book" | "buy" | "call" | "checkIn" |
"continue" | "create" | "do" | "download" | "filter" |
"find" | "get" | "go" | "log" | "open" | "order" |
"pay" | "play" | "playSound" | "post" | "request" |
"run" | "search" | "send" | "set" | "share" |
"start" | "startNavigation" | "toggle" | "turnOff" |
"turnOn" | "view"
Example
1await Intent.requestConfirmation(
2 "set",
3 PickColorIntent()
4)
Execution behavior:
- Displays a Snippet UI for confirmation
- If the user confirms → Promise resolves and script continues
- If the user cancels → execution stops (system-driven behavior)
6. The “Show Snippet Intent” Action in Shortcuts (iOS 26+)
iOS 26 adds a new Shortcuts action:
Show Snippet Intent
This action is the only correct way to display SnippetIntent UI.
Comparison with Other Scripting Actions
| Shortcuts Action |
UI Shown |
Supports SnippetIntent |
Usage |
| Run Script |
None |
No |
Background logic |
| Run Script in App |
Fullscreen UI inside Scripting |
No |
Rich app-level UI |
| Show Snippet Intent (iOS 26+) |
Snippet card UI |
Yes |
SnippetIntent flows |
Usage
- Add “Show Snippet Intent” in Shortcuts
- Select a Scripting script project
- The script must return
Intent.snippetIntent(...)
- Shortcuts renders the UI in a Snippet card
7. IntentMemoryStorage — Cross-Intent State Store
Why It Exists
Every AppIntent execution runs in an isolated environment:
- After an AppIntent
perform() completes → its execution context is destroyed
- After a script calls
Script.exit() → the JS context is destroyed
This means local variables cannot persist between AppIntent calls.
Snippet flows commonly involve:
PickColor → SetColor → ShowResult
Therefore a cross-Intent state mechanism is required.
IntentMemoryStorage API
1namespace IntentMemoryStorage {
2 function get<T>(key: string): T | null
3 function set(key: string, value: any): void
4 function remove(key: string): void
5 function contains(key: string): boolean
6 function clear(): void
7 function keys(): string[]
8}
Purpose
- Store small pieces of shared data across multiple AppIntents
- Works during the entire Shortcut flow
- Ideal for selections, temporary configuration, or intent-to-intent handoff
Example
1IntentMemoryStorage.set("color", "systemBlue")
2
3const color = IntentMemoryStorage.get<Color>("color")
Guidelines
Not recommended for large data.
For large data:
- Use
Storage (persistent key-value store)
- Or save files via
FileManager in appGroupDocumentsDirectory
IntentMemoryStorage should be treated as temporary, lightweight state.
8. Full Example Combining All Features (iOS 26+)
app_intents.tsx
1export const SetColorIntent = AppIntentManager.register({
2 name: "SetColorIntent",
3 protocol: AppIntentProtocol.AppIntent,
4 perform: async (color: Color) => {
5 IntentMemoryStorage.set("color", color)
6 }
7})
8
9export const PickColorIntent = AppIntentManager.register<void>({
10 name: "PickColorIntent",
11 protocol: AppIntentProtocol.SnippetIntent,
12 perform: async () => {
13 return <PickColorView />
14 }
15})
16
17export const ShowResultIntent = AppIntentManager.register({
18 name: "ShowResultIntent",
19 protocol: AppIntentProtocol.SnippetIntent,
20 perform: async ({ content }: { content: string }) => {
21 const color = IntentMemoryStorage.get<Color>("color") ?? "systemBlue"
22 return <ResultView content={content} color={color} />
23 }
24})
intent.tsx
1async function runIntent() {
2
3 // 1. Ask the user to confirm setting the color via Snippet
4 await Intent.requestConfirmation(
5 "set",
6 PickColorIntent()
7 )
8
9 // 2. Read Shortcuts input
10 const textContent =
11 Intent.shortcutParameter?.type === "text"
12 ? Intent.shortcutParameter.value
13 : "No text parameter from Shortcuts"
14
15 // 3. Create final SnippetIntent UI
16 const snippetIntentValue = Intent.snippetIntent({
17 snippetIntent: ShowResultIntent({ content: textContent })
18 })
19
20 Script.exit(snippetIntentValue)
21}
22
23runIntent()
Shortcuts Flow
- User provides text
- “Show Snippet Intent” runs the script
- Script displays PickColorIntent confirmation UI via requestConfirmation
- After confirmation, displays ShowResultIntent Snippet UI
- Uses IntentMemoryStorage to persist the selected color
9. Summary
This document introduces all new Scripting features added for iOS 26+:
-
SnippetIntent
- Registered using
AppIntentManager
- Returns TSX UI
- Requires iOS 26+
-
Intent.snippetIntent
- Wraps a SnippetIntent for Script.exit
-
Intent.requestConfirmation
- Presents a confirmation Snippet UI
- Requires SnippetIntent
-
“Show Snippet Intent” action in Shortcuts
- Required to display SnippetIntent UI
-
IntentMemoryStorage
- Lightweight cross-AppIntent storage
- Not suitable for large binary/content data
- Complements multi-step Snippet flows