title: Breaking Change: Widget Shortcut Lists description: Replaces four shortcut slots and Button.shortcut with an editable Shortcuts list and zero-based Button.shortcutIndex. Adds Widget.shortcutCount. Reconfigure actions in existing test widgets; deleting or reordering items changes their indices.
Scripting is an app that allows you to create iOS Home Screen widgets using TypeScript and React-like TSX syntax.
You can define your widget’s UI inside a widget.tsx file using SwiftUI-inspired components.
1. Quick Start
Step 1: Create a Script Project
- Open the Scripting app.
- Create a new script project and give your widget a name.
Step 2: Add a widget.tsx File
- In the project, create a new file named
widget.tsx. - Define your widget’s interface using a functional component.
- Import the required components and APIs from the
scriptingpackage.
Example:
Calling Widget.present() renders the widget on the Home Screen.
2. Accessing the Widget Context
You can use the following Widget API properties to adapt layout and content:
These properties help you dynamically adjust content and layout based on the widget’s size or user preferences.
On iOS 27+, Widget.family also supports systemExtraLargePortrait for portrait extra-large layouts.
3. Add to Home Screen
- Add the Scripting widget to your iOS Home Screen.
- Long-press the widget and tap Edit Widget.
- Select the script you created and configure its Parameter if needed.
Once configured, the UI defined in your widget.tsx file will appear directly on the Home Screen.
4. Building the View
Use SwiftUI-inspired built-in components such as VStack, HStack, Text, and Image to compose your widget UI.
You can also separate logic and UI across multiple files and import them as needed.
5. Development Constraints and Best Practices
Hooks Are Not Active in Widgets
While you can technically use React hooks such as useState or useEffect, they don’t take effect inside widgets because widgets are rendered once and have no persistent interactive lifecycle.
Avoid relying on dynamic state logic.
Memory Limit
iOS enforces an approximate 30 MB memory limit per widget. To stay within it:
- Avoid deep view hierarchies.
- Minimize image usage.
- Avoid memory leaks or large data references.
If a widget fails to render or appears blank, it’s often due to exceeding this limit.
Context Is Immediately Destroyed
After calling Widget.present(...), the current execution context is immediately destroyed:
- Prepare all data before calling
Widget.present(). - Do not place code after
Widget.present(), as it will never run. - Treat the widget function as a one-time UI renderer.
6. Interaction Support
Although widgets are mostly static, basic interactivity can be achieved via AppIntent:
- Use
<Button>or<Toggle>components to trigger AppIntents. - See the Interactive Widget and LiveActivity documentation for more details.
7. View Compatibility
Not all SwiftUI views are supported in WidgetKit. Some layout containers and visual effects are unavailable. Refer to Apple’s official documentation: Supported SwiftUI views in WidgetKit.
8. Widget Preview Limitations
Widget previews inside the Scripting app are only approximations. The actual rendering on the Home Screen may differ slightly in:
- Text alignment
- Widget size
- Corner radius
- Layout behavior
Always test on the Home Screen to verify the final layout.
9. Refreshing Widgets
General Refresh Methods
- Call
Widget.reloadAll()to refresh all widgets (both user and developer kinds). - You can invoke it in
index.tsxor inside an AppIntent. - Alternatively, use the Refresh Widgets button in the Scripting app during development.
This enables rapid iteration on layout and logic.
New: User Widgets vs Developer Widgets
Scripting now distinguishes between two kinds of widgets:
Each kind has its own kind identifier, allowing isolation between user and developer widgets.
This ensures that refreshing test widgets doesn’t affect the user’s actual widgets.
New Refresh Methods
These methods were introduced to isolate user and developer environments. When developing, refreshing Test Widgets won’t disturb any user widgets already installed.
Example
Usage Recommendations
- During development: use
Widget.reloadTestWidgets()for testing. - For production or user updates: use
Widget.reloadUserWidgets()orWidget.reloadAll().
This separation helps prevent interference between development experiments and user-facing widgets.
10. Documentation and Support
- Refer to the Views Documentation for a complete list of available components and modifiers.
- Check the API Documentation for advanced integrations (e.g., Calendar, FileManager, AVPlayer, etc.).
11. Using Widget.preview for In-App Development Preview
During development, you can use Widget.preview() in your index.tsx to preview layout and parameter configurations without leaving the app.
Method: Widget.preview(options)
This method simulates widget rendering for various sizes and parameters, suitable for development-only testing.
It can only be called from the index.tsx environment (not from widget.tsx or intent.tsx).
Parameters
Example
This allows testing visual differences under different parameter inputs such as colors, text, or layout configurations.
Notes
- Must be called from
index.tsx— not fromwidget.tsxorintent.tsx. - If the parameter format is invalid, an error will be thrown.
- Preview results are still subject to the limitations listed in Section 8; always verify the final look on the Home Screen.
Portrait Extra-Large Preview (iOS 27+)
Select systemExtraLargePortrait in the preview's family picker, or pass it to Widget.preview from index.tsx:
The in-app preview uses a simulated size of 300 × 628 pt, the portrait counterpart of the existing 628 × 300 pt extra-large preview. Actual Home Screen widget dimensions depend on the device; use Widget.displaySize to adapt your layout.
12. System Shortcuts in Widget Buttons (iOS 27+)
On iOS 27 and later, buttons in your existing User Widgets, Test Widgets, Transparent Background Widgets, and Blur Background Widgets can run actions chosen in the widget settings. Each widget has an editable Shortcuts list. Add, remove, or reorder actions using the system configuration interface; Scripting no longer limits the list to four slots. An item can run a custom shortcut, an App Shortcut, a system action, or open an app.
Configure the Actions
- Add an existing Scripting widget to the Home Screen and select your script.
- Long-press the widget and choose Edit Widget.
- In Shortcuts, use Add New Item to select actions. Remove or reorder items as needed.
- Tap a button on the Home Screen to run its configured action.
The script references an item's zero-based position with shortcutIndex: 0 selects the first item and 1 the second. You control each button's label, layout, and style:
In Edit Widget, add your desired actions as the first and second items. Reordering or deleting an item changes the indices of subsequent items; update button labels or the configuration order accordingly.
Widget.shortcutCount reports the number of configured items. For example, generate a button for each item:
The count is 0 in the in-app preview and on systems before iOS 27. It does not expose shortcut names or values.
Breaking change in 3.2.2: the unreleased four-slot configuration and shortcut="shortcut1" API are replaced by the list and shortcutIndex={0}. Existing test widgets using the old configuration need their actions configured again.
Button Contract and Limitations
shortcutIndexmust be a nonnegative safe integer within the configured list. It is a position, not a shortcut name or ID. Available list sizes depend on the system configuration interface.- A button uses one action source:
shortcutIndex,intent, oraction. Do not combine them on the same button. - Multiple buttons can reference the same index. Other buttons can continue to use script AppIntents, and When Interacting still controls taps outside the buttons.
- The system stores the selected action in the widget configuration. Scripts cannot read or construct its
SystemShortcutvalue, and do not need to register an AppIntent for it. - If an index is out of range or the context is unsupported, Scripting keeps the label and reports a diagnostic instead of executing a shortcut or script callback.
- Shortcut buttons require an iOS 27+ widget family that supports buttons. They are unavailable in
accessoryInline, app views, Live Activities, and Control Widgets. - The in-app preview lets you check layout, but cannot configure or execute these actions. Test them on the Home Screen. Actions that need interaction may open Shortcuts.
