From 2aeacf29216befeeaa05c32ad6fd938c1886f04a Mon Sep 17 00:00:00 2001 From: Philipp Andreas Paul Date: Fri, 25 Sep 2026 13:16:25 +0000 Subject: [PATCH 1/4] docs(JS): add local context page and document the configuration builder Documents the two client-library APIs that shipped with the AmplifyContext migration in aws-amplify v6.21.0 and v6.22.0. New page frontend/local-context covers createAmplifyContext: what a local context is, when to use one on the client (several profiles signed in at once, tenant switching, environment switching), how to create and use one, that libraryOptions are per context, the two context errors, and why server-side code keeps using runWithAmplifyServerContext with the /server exports. connect-to-existing-resources now leads with Amplify.configure(outputs) and presents the alternatives as tabbed boxes: configuration builder, manual ResourcesConfig, and a hand-written outputs file. Each category example gets the same two-tab treatment, and every example shows the createAmplifyContext alternative next to Amplify.configure. The required-fields tables described amplify_outputs.json fields while every JS example builds a ResourcesConfig, so they are split per platform group: JS readers get ResourcesConfig[K] paths, native platforms keep the outputs fields. Both are trimmed to required fields and link to the type definition or the schema for the rest. The outputs tables are also refreshed against schema v1.5: EMAIL as an MFA method, AWS_LAMBDA as an authorization type, amazon_connect, storage buckets, and the relaxed notifications required list. The server-side rendering page links to the new page for client-side code that needs several configurations at once. --- src/directory/directory.mjs | 3 + .../connect-to-existing-resources/index.mdx | 784 ++++++++++++++++-- .../frontend/local-context/index.mdx | 202 +++++ .../frontend/server-side-rendering/index.mdx | 6 + 4 files changed, 907 insertions(+), 88 deletions(-) create mode 100644 src/pages/[platform]/frontend/local-context/index.mdx diff --git a/src/directory/directory.mjs b/src/directory/directory.mjs index c812c8d9894..b0d80164c6d 100644 --- a/src/directory/directory.mjs +++ b/src/directory/directory.mjs @@ -843,6 +843,9 @@ export const directory = { } ] }, + { + path: 'src/pages/[platform]/frontend/local-context/index.mdx' + }, { path: 'src/pages/[platform]/frontend/server-side-rendering/index.mdx', children: [ diff --git a/src/pages/[platform]/frontend/connect-to-existing-resources/index.mdx b/src/pages/[platform]/frontend/connect-to-existing-resources/index.mdx index 826899e520c..2a60e0b1d23 100644 --- a/src/pages/[platform]/frontend/connect-to-existing-resources/index.mdx +++ b/src/pages/[platform]/frontend/connect-to-existing-resources/index.mdx @@ -3,7 +3,7 @@ import { getCustomStaticPath } from '@/utils/getCustomStaticPath'; export const meta = { title: 'Connect to existing AWS resources', description: - 'Use Amplify client libraries with your own AWS infrastructure. Configure Auth, Data, Storage, Analytics, Geo, and Notifications programmatically or via amplify_outputs.json — no Amplify backend required.', + 'Use Amplify client libraries with your own AWS infrastructure. Configure Auth, Data, Storage, Analytics, Geo, and Notifications programmatically or via amplify_outputs.json, with no Amplify backend required.', platforms: [ 'android', 'angular', @@ -32,7 +32,7 @@ export function getStaticProps(context) { Amplify client libraries can be used **independently** without the Amplify backend workflow. If you've provisioned AWS resources with CDK, Terraform, CloudFormation, or the AWS Console, you can connect Amplify libraries directly to those resources. -This means you can adopt Amplify's client libraries for authentication, data, storage, and more — while keeping full control over your infrastructure. +This means you can adopt Amplify's client libraries for authentication, data, storage, and more, while keeping full control over your infrastructure. ## When to use this approach @@ -45,39 +45,90 @@ This means you can adopt Amplify's client libraries for authentication, data, st -There are two ways to configure Amplify client libraries with your own resources: +The default path is a generated `amplify_outputs.json` file that you hand to `Amplify.configure()`: -### Option 1: Manual `amplify_outputs.json` +```typescript +import { Amplify } from 'aws-amplify'; +import outputs from './amplify_outputs.json'; -Create an `amplify_outputs.json` file in your project with the configuration for your resources. See the [full `amplify_outputs.json` specification](/[platform]/reference/amplify_outputs/) for all supported fields. +Amplify.configure(outputs); +``` -```json title="amplify_outputs.json" -{ - "version": "1", - "auth": { - "aws_region": "us-east-1", - "user_pool_id": "us-east-1_abc123", - "user_pool_client_id": "abcdef123456" - }, - "storage": { - "aws_region": "us-east-1", - "bucket_name": "my-app-bucket" - } -} +When you own the infrastructure there is no generated file, so you provide the configuration yourself. There are three ways to do that: + + + + + +`createConfigurationBuilder`, exported from `aws-amplify`, assembles a `ResourcesConfig` step by step. Every method returns the builder, and `build()` produces a frozen `ResourcesConfig` that `Amplify.configure()` accepts: + +```typescript +import { Amplify, createAmplifyContext, createConfigurationBuilder } from 'aws-amplify'; + +const config = createConfigurationBuilder() + .auth({ + Cognito: { + userPoolId: 'us-east-1_abc123', + userPoolClientId: 'abcdef123456' + } + }) + .storage({ S3: { bucket: 'my-app-bucket', region: 'us-east-1' } }) + .build(); + +Amplify.configure(config); +// or +const ctx = createAmplifyContext(config); ``` -Then configure Amplify in your app: +| Method | Description | +|--------|-------------| +| `from(seed)` | Merges an existing configuration in. Accepts anything `Amplify.configure()` accepts: a `ResourcesConfig`, a legacy `aws-exports` object, `amplify_outputs.json`, or **another builder**. Can be called repeatedly to accumulate, and is also available as `createConfigurationBuilder({ from })`. | +| `add(category, value)` | Adds a category, **replacing** it entirely if already present. | +| `patch(category, partial)` | Deep-merges a partial into a category, keeping nested values you don't mention. Creates the category if it doesn't exist. | +| `auth()`, `api()`, `storage()`, `analytics()`, `geo()`, `notifications()`, `interactions()`, `predictions()` | Shorthands for `add()` with that category: `.auth(config)` is `.add('Auth', config)`. | +| `build()` | Returns the finished, frozen `ResourcesConfig`. | + +**Configure part of a configuration.** `patch()` deep-merges into a category, so you can change one nested value and leave the rest of it alone. This is the difference between the two write methods: `add('Auth', …)` (and its `auth()` shorthand) discards whatever `Auth` held, while `patch()` keeps it. ```typescript -import { Amplify } from 'aws-amplify'; -import outputs from './amplify_outputs.json'; +const config = createConfigurationBuilder({ from: outputs }) + // Everything else under Auth.Cognito survives + .patch('Auth', { Cognito: { userPoolId: 'us-east-1_dev123' } }) + // Add or overwrite a category outright, whether or not the outputs file carries it + .add('Storage', { S3: { bucket: 'my-platform-bucket', region: 'us-east-1' } }) + .build(); +``` -Amplify.configure(outputs); +**Extend a base builder.** A builder is itself a valid seed, so one shared base can produce environment-specific configurations without being mutated: + +```typescript +// Owned by your platform team, never passed to configure() directly +const base = createConfigurationBuilder({ from: outputs }); + +const dev = createConfigurationBuilder({ from: base }) + .patch('Auth', { Cognito: { userPoolId: 'us-east-1_dev123' } }) + .build(); + +const prod = createConfigurationBuilder({ from: base }) + .patch('Auth', { Cognito: { userPoolId: 'us-east-1_prod789' } }) + .build(); +``` + +**Write generators.** Because `build()` returns a plain object, a function that closes over the shared base turns a single varying value into a whole configuration: + +```typescript +const withUserPool = (userPoolId: string) => + createConfigurationBuilder({ from: base }) + .patch('Auth', { Cognito: { userPoolId } }) + .build(); + +Amplify.configure(withUserPool('us-east-1_dev123')); ``` -### Option 2: Direct `Amplify.configure()` with a `ResourcesConfig` object + + -Pass the configuration directly without a JSON file: +Pass a `ResourcesConfig` object straight to `Amplify.configure()`. Nothing is merged for you, so every call states the complete configuration: ```typescript import { Amplify } from 'aws-amplify'; @@ -102,6 +153,45 @@ Amplify.configure({ }); ``` +This is the most direct option when your app has exactly one configuration and it never varies at runtime. + + + + +Keep the configuration in a file of your own and import it, the way a generated `amplify_outputs.json` is imported. Amplify only cares about the shape, so the file name is yours to choose. See the [full `amplify_outputs.json` specification](/[platform]/reference/amplify_outputs/) for every supported field: + +```json title="my_resources.json" +{ + "version": "1.5", + "auth": { + "aws_region": "us-east-1", + "user_pool_id": "us-east-1_abc123", + "user_pool_client_id": "abcdef123456" + }, + "storage": { + "aws_region": "us-east-1", + "bucket_name": "my-app-bucket" + } +} +``` + +```typescript +import { Amplify, createAmplifyContext } from 'aws-amplify'; +import resources from './my_resources.json'; + +Amplify.configure(resources); +// or +const ctx = createAmplifyContext(resources); +``` + +Because the file is checked in as data, this option keeps the configuration out of your application code while still letting you hold several of them: one file per environment, each imported where it is needed. + + + + + +The built `ResourcesConfig` is a plain object either way, so it works anywhere a configuration is accepted: pass it to `Amplify.configure()` to set it globally, or to `createAmplifyContext()` to create an isolated [local context](/[platform]/frontend/local-context/) instead of touching global state. + @@ -114,7 +204,7 @@ Create an `amplify_outputs.json` file in your Xcode project. See the [full speci ```json title="amplify_outputs.json" { - "version": "1", + "version": "1.5", "auth": { "aws_region": "us-east-1", "user_pool_id": "us-east-1_abc123", @@ -152,9 +242,9 @@ try Amplify.configure(config) ``` This approach is ideal for: -- **Unit testing** — Configure Amplify without bundling JSON files -- **Environment switching** — Build different configurations for dev/staging/prod -- **Dynamic configuration** — Fetch configuration from a remote source at runtime +- **Unit testing:** Configure Amplify without bundling JSON files +- **Environment switching:** Build different configurations for dev/staging/prod +- **Dynamic configuration:** Fetch configuration from a remote source at runtime @@ -168,7 +258,7 @@ Create an `amplify_outputs.json` file in your `app/src/main/res/raw/` directory. ```json title="amplify_outputs.json" { - "version": "1", + "version": "1.5", "auth": { "aws_region": "us-east-1", "user_pool_id": "us-east-1_abc123", @@ -207,9 +297,9 @@ Amplify.configure(config, applicationContext) ``` This approach is ideal for: -- **Unit testing** — Configure Amplify without bundling JSON files -- **Environment switching** — Build different configurations for dev/staging/prod -- **Dynamic configuration** — Fetch configuration from a remote source at runtime +- **Unit testing:** Configure Amplify without bundling JSON files +- **Environment switching:** Build different configurations for dev/staging/prod +- **Dynamic configuration:** Fetch configuration from a remote source at runtime @@ -223,7 +313,7 @@ Create an `amplify_outputs.json` file with your resource configuration. See the ```json title="amplify_outputs.json" { - "version": "1", + "version": "1.5", "auth": { "aws_region": "us-east-1", "user_pool_id": "us-east-1_abc123", @@ -267,9 +357,9 @@ await Amplify.configure(config); ``` This approach is ideal for: -- **Unit testing** — Configure Amplify without bundling files -- **Environment switching** — Build different configurations for dev/staging/prod -- **Dynamic configuration** — Fetch configuration from a remote source at runtime +- **Unit testing:** Configure Amplify without bundling files +- **Environment switching:** Build different configurations for dev/staging/prod +- **Dynamic configuration:** Fetch configuration from a remote source at runtime @@ -279,7 +369,49 @@ Connect to an existing Cognito User Pool and Identity Pool. + + + + +```typescript +import { Amplify, createAmplifyContext, createConfigurationBuilder } from 'aws-amplify'; + +const config = createConfigurationBuilder() + .auth({ + Cognito: { + userPoolId: 'us-east-1_abc123', + userPoolClientId: 'abcdef123456', + identityPoolId: 'us-east-1:11111111-2222-3333-4444-555555555555', + loginWith: { + email: true + }, + signUpVerificationMethod: 'code', + userAttributes: { + email: { required: true } + }, + allowGuestAccess: true, + passwordFormat: { + minLength: 8, + requireLowercase: true, + requireUppercase: true, + requireNumbers: true, + requireSpecialCharacters: true + } + } + }) + .build(); + +Amplify.configure(config); +// or +const ctx = createAmplifyContext(config); +``` + + + + ```typescript +import { Amplify } from 'aws-amplify'; + Amplify.configure({ Auth: { Cognito: { @@ -306,6 +438,10 @@ Amplify.configure({ }); ``` + + + + @@ -439,16 +575,35 @@ await Amplify.configure(config); ### Auth required fields + + +Fields of `ResourcesConfig['Auth']`, the object both tabs above build: + +| Field | Required | Description | +|-------|----------|-------------| +| `Cognito.userPoolId` | With a user pool | Cognito User Pool ID | +| `Cognito.userPoolClientId` | With a user pool | Cognito app client ID | +| `Cognito.identityPoolId` | With an identity pool | Cognito Identity Pool ID, needed for guest access and for IAM-signed requests | + +There is no region field: the region is read from the user pool and identity pool IDs. `Cognito` accepts the user pool fields, the identity pool fields, or both, so an identity-pool-only configuration cannot carry `userPoolId`. + +Every other field is optional. See [`AuthConfig`](https://github.com/aws-amplify/amplify-js/blob/main/packages/core/src/singleton/Auth/types.ts) for the full type. + + + + + +Fields of the `auth` block in `amplify_outputs.json`: + | Field | Required | Description | |-------|----------|-------------| | `awsRegion` | Yes | AWS region (e.g. `us-east-1`) | | `userPoolId` | Yes | Cognito User Pool ID | | `userPoolClientId` | Yes | Cognito app client ID | -| `identityPoolId` | No | Cognito Identity Pool ID (needed for guest access and IAM-based auth) | -| `passwordPolicy` | No | Password requirements (min length, character types) | -| `oauth` | No | OAuth/Hosted UI configuration (social sign-in) | -| `mfaConfiguration` | No | MFA mode: `NONE`, `OPTIONAL`, or `REQUIRED` | -| `mfaMethods` | No | MFA types: `SMS`, `TOTP` | + +Every other field is optional. See the [`amplify_outputs.json` schema](https://github.com/aws-amplify/amplify-backend/blob/main/packages/client-config/src/client-config-schema/schema_v1.5.json) for the full shape. + + ## Configure Data (AWS AppSync) @@ -456,26 +611,59 @@ Connect to an existing AppSync GraphQL API. -```json title="amplify_outputs.json" -{ - "version": "1", - "data": { - "aws_region": "us-east-1", - "url": "https://abc123.appsync-api.us-east-1.amazonaws.com/graphql", - "api_key": "da2-abcdefghijklmno", - "default_authorization_type": "API_KEY", - "authorization_types": ["API_KEY"] - } -} + + + + +```typescript +import { Amplify, createAmplifyContext, createConfigurationBuilder } from 'aws-amplify'; + +const config = createConfigurationBuilder() + .api({ + GraphQL: { + endpoint: + 'https://abc123.appsync-api.us-east-1.amazonaws.com/graphql', + region: 'us-east-1', + apiKey: 'da2-abcdefghijklmno', + defaultAuthMode: 'apiKey' + } + }) + .build(); + +Amplify.configure(config); +// or +const ctx = createAmplifyContext(config); ``` + + + ```typescript import { Amplify } from 'aws-amplify'; -import outputs from './amplify_outputs.json'; -Amplify.configure(outputs); +Amplify.configure({ + API: { + GraphQL: { + endpoint: + 'https://abc123.appsync-api.us-east-1.amazonaws.com/graphql', + region: 'us-east-1', + apiKey: 'da2-abcdefghijklmno', + defaultAuthMode: 'apiKey' + } + } +}); ``` + + + + + + +In a `ResourcesConfig` object the AppSync API lives under `API.GraphQL`, and `defaultAuthMode` takes the client-side value, one of `apiKey`, `userPool`, `identityPool`, `oidc`, `lambda`, or `none`, rather than the `API_KEY` style used in `amplify_outputs.json`. + + + @@ -540,13 +728,36 @@ await Amplify.configure(config); ### Data required fields + + +Fields of `ResourcesConfig['API']`, the object both tabs above build: + +| Field | Required | Description | +|-------|----------|-------------| +| `GraphQL.endpoint` | Yes | AppSync GraphQL endpoint URL | +| `GraphQL.defaultAuthMode` | Yes | `apiKey`, `userPool`, `identityPool`, `oidc`, `lambda`, or `none`. `iam` is the deprecated spelling of `identityPool` | +| `GraphQL.apiKey` | With `apiKey` auth | AppSync API key | +| `GraphQL.region` | With `identityPool` auth | Region used to sign the request | + +Every other field is optional. See [`APIConfig`](https://github.com/aws-amplify/amplify-js/blob/main/packages/core/src/singleton/API/types.ts) for the full type. + + + + + +Fields of the `data` block in `amplify_outputs.json`: + | Field | Required | Description | |-------|----------|-------------| | `awsRegion` | Yes | AWS region | | `url` | Yes | AppSync GraphQL endpoint URL | -| `defaultAuthorizationType` | Yes | Default auth mode: `API_KEY`, `AMAZON_COGNITO_USER_POOLS`, `AWS_IAM`, or `OPENID_CONNECT` | -| `authorizationTypes` | Yes | All supported auth modes | -| `apiKey` | No | Required if using `API_KEY` auth | +| `defaultAuthorizationType` | Yes | Default auth mode: `AMAZON_COGNITO_USER_POOLS`, `API_KEY`, `AWS_IAM`, `AWS_LAMBDA`, or `OPENID_CONNECT` | +| `authorizationTypes` | Yes | Every auth mode the API accepts, from the same list | +| `apiKey` | With `API_KEY` auth | AppSync API key | + +Every other field is optional. See the [`amplify_outputs.json` schema](https://github.com/aws-amplify/amplify-backend/blob/main/packages/client-config/src/client-config-schema/schema_v1.5.json) for the full shape. + + ## Configure Storage (Amazon S3) @@ -554,7 +765,35 @@ Connect to an existing S3 bucket. + + + + +```typescript +import { Amplify, createAmplifyContext, createConfigurationBuilder } from 'aws-amplify'; + +const config = createConfigurationBuilder() + .auth({ + Cognito: { + userPoolId: 'us-east-1_abc123', + userPoolClientId: 'abcdef123456', + identityPoolId: 'us-east-1:11111111-2222-3333-4444-555555555555' + } + }) + .storage({ S3: { bucket: 'my-app-bucket', region: 'us-east-1' } }) + .build(); + +Amplify.configure(config); +// or +const ctx = createAmplifyContext(config); +``` + + + + ```typescript +import { Amplify } from 'aws-amplify'; + Amplify.configure({ Auth: { Cognito: { @@ -572,6 +811,53 @@ Amplify.configure({ }); ``` + + + + +### Multiple buckets + + + + + +```typescript +const config = createConfigurationBuilder() + .storage({ + S3: { + bucket: 'primary-bucket', + region: 'us-east-1', + buckets: { + media: { bucketName: 'my-media-bucket', region: 'us-east-1' }, + logs: { bucketName: 'my-logs-bucket', region: 'us-west-2' } + } + } + }) + .build(); +``` + + + + +```typescript +Amplify.configure({ + Storage: { + S3: { + bucket: 'primary-bucket', + region: 'us-east-1', + buckets: { + media: { bucketName: 'my-media-bucket', region: 'us-east-1' }, + logs: { bucketName: 'my-logs-bucket', region: 'us-west-2' } + } + } + } +}); +``` + + + + + @@ -704,11 +990,33 @@ Storage requires Auth (Cognito Identity Pool) for authorization. Always configur ### Storage required fields + + +Fields of `ResourcesConfig['Storage']`, the object both tabs above build: + +| Field | Required | Description | +|-------|----------|-------------| +| `S3.bucket` | For the default bucket | Bucket used by calls that do not name one | +| `S3.region` | For the default bucket | Region of that bucket | +| `S3.buckets[name].bucketName`, `S3.buckets[name].region` | With additional buckets | Each extra bucket is keyed by the friendly name you pass to the Storage APIs | + +Every other field is optional. See [`StorageConfig`](https://github.com/aws-amplify/amplify-js/blob/main/packages/core/src/singleton/Storage/types.ts) for the full type. + + + + + +Fields of the `storage` block in `amplify_outputs.json`: + | Field | Required | Description | |-------|----------|-------------| | `awsRegion` | Yes | AWS region | | `bucketName` | Yes | Default S3 bucket name | -| `buckets` | No | Additional named buckets for multi-bucket setups | +| `buckets[].name`, `buckets[].bucketName`, `buckets[].awsRegion` | With additional buckets | All three are required on every entry | + +Every other field is optional. See the [`amplify_outputs.json` schema](https://github.com/aws-amplify/amplify-backend/blob/main/packages/client-config/src/client-config-schema/schema_v1.5.json) for the full shape. + + ## Configure Analytics (Amazon Pinpoint) @@ -716,18 +1024,47 @@ Connect to an existing Pinpoint application. -```json title="amplify_outputs.json" -{ - "version": "1", - "analytics": { - "amazon_pinpoint": { - "aws_region": "us-east-1", - "app_id": "abc123def456" + + + + +```typescript +import { Amplify, createAmplifyContext, createConfigurationBuilder } from 'aws-amplify'; + +const config = createConfigurationBuilder() + .analytics({ + Pinpoint: { + appId: 'abc123def456', + region: 'us-east-1' + } + }) + .build(); + +Amplify.configure(config); +// or +const ctx = createAmplifyContext(config); +``` + + + + +```typescript +import { Amplify } from 'aws-amplify'; + +Amplify.configure({ + Analytics: { + Pinpoint: { + appId: 'abc123def456', + region: 'us-east-1' } } -} +}); ``` + + + + @@ -784,35 +1121,103 @@ await Amplify.configure(config); +### Analytics required fields + + + +Fields of `ResourcesConfig['Analytics']`, the object both tabs above build: + +| Field | Required | Description | +|-------|----------|-------------| +| `Pinpoint.appId` | Yes | Pinpoint application (project) ID | +| `Pinpoint.region` | Yes | Region of the Pinpoint project | + +Every other field is optional. See [`AnalyticsConfig`](https://github.com/aws-amplify/amplify-js/blob/main/packages/core/src/singleton/Analytics/types.ts) for the full type. + + + + + +Fields of the `analytics.amazon_pinpoint` block in `amplify_outputs.json`: + +| Field | Required | Description | +|-------|----------|-------------| +| `awsRegion` | Yes | AWS region of the Pinpoint project | +| `appId` | Yes | Pinpoint application (project) ID | + +Every other field is optional. See the [`amplify_outputs.json` schema](https://github.com/aws-amplify/amplify-backend/blob/main/packages/client-config/src/client-config-schema/schema_v1.5.json) for the full shape. + + + ## Configure Geo (Amazon Location Service) Connect to existing Location Service resources. -```json title="amplify_outputs.json" -{ - "version": "1", - "geo": { - "aws_region": "us-east-1", - "maps": { - "items": { - "myMap": { "style": "VectorEsriStreets" } + + + + +```typescript +import { Amplify, createAmplifyContext, createConfigurationBuilder } from 'aws-amplify'; + +const config = createConfigurationBuilder() + .geo({ + LocationService: { + region: 'us-east-1', + maps: { + items: { myMap: { style: 'VectorEsriStreets' } }, + default: 'myMap' }, - "default": "myMap" - }, - "search_indices": { - "items": ["myPlaceIndex"], - "default": "myPlaceIndex" - }, - "geofence_collections": { - "items": ["myGeofenceCollection"], - "default": "myGeofenceCollection" + searchIndices: { + items: ['myPlaceIndex'], + default: 'myPlaceIndex' + }, + geofenceCollections: { + items: ['myGeofenceCollection'], + default: 'myGeofenceCollection' + } + } + }) + .build(); + +Amplify.configure(config); +// or +const ctx = createAmplifyContext(config); +``` + + + + +```typescript +import { Amplify } from 'aws-amplify'; + +Amplify.configure({ + Geo: { + LocationService: { + region: 'us-east-1', + maps: { + items: { myMap: { style: 'VectorEsriStreets' } }, + default: 'myMap' + }, + searchIndices: { + items: ['myPlaceIndex'], + default: 'myPlaceIndex' + }, + geofenceCollections: { + items: ['myGeofenceCollection'], + default: 'myGeofenceCollection' + } } } -} +}); ``` + + + + @@ -873,6 +1278,40 @@ Amplify.configure(config, applicationContext) +### Geo required fields + + + +Fields of `ResourcesConfig['Geo']`, the object both tabs above build: + +| Field | Required | Description | +|-------|----------|-------------| +| `LocationService.region` | Yes | Region of the Location Service resources | +| `LocationService.maps.items`, `LocationService.maps.default` | With `maps` | Maps keyed by name, plus the default map name | +| `LocationService.searchIndices.items`, `LocationService.searchIndices.default` | With `searchIndices` | Place index names, plus the default index | +| `LocationService.geofenceCollections.items`, `LocationService.geofenceCollections.default` | With `geofenceCollections` | Collection names, plus the default collection | + +Every other field is optional. See [`GeoConfig`](https://github.com/aws-amplify/amplify-js/blob/main/packages/core/src/singleton/Geo/types.ts) for the full type. + + + + + +Fields of the `geo` block in `amplify_outputs.json`: + +| Field | Required | Description | +|-------|----------|-------------| +| `awsRegion` | Yes | AWS region of the Location Service resources | +| `maps.items`, `maps.default` | With `maps` | Maps keyed by name, plus the default map name | +| `searchIndices.items`, `searchIndices.default` | With `searchIndices` | Place index names, plus the default index | +| `geofenceCollections.items`, `geofenceCollections.default` | With `geofenceCollections` | Collection names, plus the default collection | + +Every other field is optional. See the [`amplify_outputs.json` schema](https://github.com/aws-amplify/amplify-backend/blob/main/packages/client-config/src/client-config-schema/schema_v1.5.json) for the full shape. + + + +Each resource group is optional on its own, but configure the ones your app actually calls: the Geo APIs need a default for the resource type they use. + ## Configure Notifications (Push) Connect to an existing Pinpoint application for push notifications. @@ -914,11 +1353,11 @@ Amplify.configure(config, applicationContext) - + ```json title="amplify_outputs.json" { - "version": "1", + "version": "1.5", "notifications": { "aws_region": "us-east-1", "amazon_pinpoint_app_id": "abc123def456", @@ -929,6 +1368,90 @@ Amplify.configure(config, applicationContext) + + + + + + +```typescript +import { Amplify, createAmplifyContext, createConfigurationBuilder } from 'aws-amplify'; + +const config = createConfigurationBuilder() + .notifications({ + PushNotification: { + Pinpoint: { appId: 'abc123def456', region: 'us-east-1' } + }, + InAppMessaging: { + Pinpoint: { appId: 'abc123def456', region: 'us-east-1' } + } + }) + .build(); + +Amplify.configure(config); +// or +const ctx = createAmplifyContext(config); +``` + + + + +```typescript +import { Amplify } from 'aws-amplify'; + +Amplify.configure({ + Notifications: { + PushNotification: { + Pinpoint: { appId: 'abc123def456', region: 'us-east-1' } + }, + InAppMessaging: { + Pinpoint: { appId: 'abc123def456', region: 'us-east-1' } + } + } +}); +``` + + + + + + + +### Notifications required fields + + + +Fields of `ResourcesConfig['Notifications']`, the object both tabs above build. At least one of `PushNotification` and `InAppMessaging` must be present: + +| Field | Required | Description | +|-------|----------|-------------| +| `PushNotification.Pinpoint.appId`, `PushNotification.Pinpoint.region` | For Pinpoint push | Pinpoint project backing push device registration | +| `PushNotification.CustomerProfiles.endpoint`, `PushNotification.CustomerProfiles.region` | For Amazon Connect push | Amazon Connect Customer Profiles endpoint backing push device registration | +| `InAppMessaging.Pinpoint.appId`, `InAppMessaging.Pinpoint.region` | For in-app messaging | Pinpoint project backing in-app messages | + +Every other field is optional. See [`NotificationsConfig`](https://github.com/aws-amplify/amplify-js/blob/main/packages/core/src/singleton/Notifications/types.ts) for the full type. + + + + + +Fields of the `notifications` block in `amplify_outputs.json`: + +| Field | Required | Description | +|-------|----------|-------------| +| `awsRegion` | For Pinpoint | AWS region of the Pinpoint project | +| `amazonPinpointAppId` | For Pinpoint | Pinpoint application ID | +| `channels` | For Pinpoint | Channels to enable: `APNS`, `FCM`, `IN_APP_MESSAGING`, `EMAIL`, or `SMS`. At least one entry, no duplicates | +| `amazonConnect.awsRegion`, `amazonConnect.endpoint` | With Amazon Connect | Customer Profiles endpoint used for push device registration | + +No field is required on its own: a Pinpoint setup needs the region, the app ID, and at least one channel, while an Amazon Connect setup needs only `amazonConnect`. + +Every other field is optional. See the [`amplify_outputs.json` schema](https://github.com/aws-amplify/amplify-backend/blob/main/packages/client-config/src/client-config-schema/schema_v1.5.json) for the full shape. + + + +In a `ResourcesConfig` object there is no `channels` list: which channels are active follows from the providers you configure, `PushNotification` and `InAppMessaging`. `amazonConnect` becomes `Notifications.PushNotification.CustomerProfiles` with `endpoint` and `region`. + ## Multi-category configuration You can configure multiple services together. This example sets up Auth, Data, and Storage in a single configuration. @@ -1028,7 +1551,45 @@ await Amplify.configure(config); + + + + +```typescript +import { Amplify, createAmplifyContext, createConfigurationBuilder } from 'aws-amplify'; + +const config = createConfigurationBuilder() + .auth({ + Cognito: { + userPoolId: 'us-east-1_abc123', + userPoolClientId: 'abcdef123456', + identityPoolId: 'us-east-1:11111111-2222-3333-4444-555555555555' + } + }) + .api({ + GraphQL: { + endpoint: + 'https://abc123.appsync-api.us-east-1.amazonaws.com/graphql', + region: 'us-east-1', + defaultAuthMode: 'userPool' + } + }) + .storage({ S3: { bucket: 'my-app-bucket', region: 'us-east-1' } }) + .build(); + +Amplify.configure(config); +// or +const ctx = createAmplifyContext(config); +``` + +Chaining also means a category can come from somewhere else entirely: seed the builder with a shared configuration and add only what this app owns. + + + + ```typescript +import { Amplify } from 'aws-amplify'; + Amplify.configure({ Auth: { Cognito: { @@ -1039,7 +1600,9 @@ Amplify.configure({ }, API: { GraphQL: { - endpoint: 'https://abc123.appsync-api.us-east-1.amazonaws.com/graphql', + endpoint: + 'https://abc123.appsync-api.us-east-1.amazonaws.com/graphql', + region: 'us-east-1', defaultAuthMode: 'userPool' } }, @@ -1052,6 +1615,10 @@ Amplify.configure({ }); ``` + + + + @@ -1182,7 +1749,28 @@ await Amplify.configure(config); -You can maintain separate `amplify_outputs.json` files per environment: +Keep one configuration per environment and select it at startup. With the builder, derive each one from a shared base so only the differing fields are restated. The generator pattern from [How it works](#how-it-works) applies directly: + +```typescript +import { Amplify, createConfigurationBuilder } from 'aws-amplify'; +import outputs from './amplify_outputs.json'; + +const base = createConfigurationBuilder({ from: outputs }); + +const withUserPool = (userPoolId: string) => + createConfigurationBuilder({ from: base }) + .patch('Auth', { Cognito: { userPoolId } }) + .build(); + +const configs = { + dev: withUserPool('us-east-1_dev123'), + prod: withUserPool('us-east-1_prod789') +}; + +Amplify.configure(configs[selectedEnvironment]); +``` + +If the environments share nothing, keep a separate outputs file per environment instead: ```typescript import devOutputs from './amplify_outputs.dev.json'; @@ -1192,6 +1780,26 @@ const outputs = process.env.NODE_ENV === 'production' ? prodOutputs : devOutputs Amplify.configure(outputs); ``` +### Several environments at the same time + +`Amplify.configure()` sets one process-wide configuration, so selecting an environment this way means the whole app moves with it, and calling `configure()` again later resets global auth state. When you need more than one environment live at once, create a [local context](/[platform]/frontend/local-context/) per configuration and pass it to the category APIs instead: + +```typescript +import { createAmplifyContext } from 'aws-amplify'; +import { fetchAuthSession } from 'aws-amplify/auth'; + +const environments = { + dev: createAmplifyContext(withUserPool('us-east-1_dev123')), + prod: createAmplifyContext(withUserPool('us-east-1_prod789')) +}; + +// Each context keeps its own configuration and its own session +const devSession = await fetchAuthSession(environments.dev); +const prodSession = await fetchAuthSession(environments.prod); +``` + +Each context is isolated, so a user signed in through one is unaffected by the others, which is what makes side-by-side environment comparison, tenant switching, and holding two profiles signed in at once possible. [Local contexts](/[platform]/frontend/local-context/) are a client-side API; for server-side runtimes, use `runWithAmplifyServerContext` with the `/server` exports as described under [Server-Side Rendering](/[platform]/frontend/server-side-rendering/). + ## `amplify_outputs.json` schema reference diff --git a/src/pages/[platform]/frontend/local-context/index.mdx b/src/pages/[platform]/frontend/local-context/index.mdx new file mode 100644 index 00000000000..28d54a9089e --- /dev/null +++ b/src/pages/[platform]/frontend/local-context/index.mdx @@ -0,0 +1,202 @@ +import { getCustomStaticPath } from '@/utils/getCustomStaticPath'; + +export const meta = { + title: 'Local context', + description: + 'Create an isolated, local AmplifyContext with createAmplifyContext and pass it directly to Amplify category APIs, without relying on global singleton configuration.', + platforms: [ + 'angular', + 'javascript', + 'nextjs', + 'react', + 'react-native', + 'vue' + ] +}; + +export const getStaticPaths = async () => { + return getCustomStaticPath(meta.platforms); +}; + +export function getStaticProps(context) { + return { + props: { + platform: context.params.platform, + meta + } + }; +} + +By default, Amplify uses a single, process-wide configuration created by `Amplify.configure()`. Every category API call (for example `signIn`, `fetchAuthSession`, or `getCurrentUser`) reads from this global singleton. That is the right default when your app talks to exactly one backend as one user at a time, but it means there is only ever **one** configuration and **one** auth state in the process. + +`aws-amplify` exposes `createAmplifyContext` for everything else. It builds a **local** `AmplifyContext`: an isolated configuration and auth handle that you pass explicitly to category APIs as their **first argument**. Each context carries its own resource configuration and its own per-context auth instance, so contexts never share state with one another or with the global singleton. + +This is not a server-side API. For server-side runtimes, keep using the server exports and `runWithAmplifyServerContext`. See [Use a local context or a server context?](#use-a-local-context-or-a-server-context). + +## When to use a local context + +Reach for `createAmplifyContext` whenever a single global configuration is not enough: + +- **Multiple profiles signed in at once:** for example a work profile and a personal profile side by side, each with its own session, without signing one out to use the other. +- **Tenant switching:** hold a context per tenant/organization so switching does not tear down and re-configure Amplify globally. +- **Environment switching:** point a build at alpha, beta, pre-prod, or prod backends from the same running app, which is useful for internal tooling, QA harnesses, and dashboards that compare environments side by side. + + + +**Tip:** If your app talks to a single backend as one user at a time, keep using `Amplify.configure()` and call the APIs without a context argument. Nothing changes for you: the context parameter is optional and fully backward compatible. + + + +## Create and use a local context + + + + + +Import `createAmplifyContext` from `aws-amplify`, pass your backend outputs to create the context, then hand that context to any category API as its **first** positional argument. Unlike `Amplify.configure()`, creating a context does **not** set a global context and does **not** dispatch any Hub events: it simply returns a new, isolated context object, ready to use immediately. + +```typescript +import { createAmplifyContext } from 'aws-amplify'; +import { signIn, getCurrentUser, fetchUserAttributes } from 'aws-amplify/auth'; +import outputs from './amplify_outputs.json'; + +// Create the context +const ctx = createAmplifyContext(outputs); + +// Sign in against the configuration carried by `ctx` +await signIn(ctx, { username, password }); + +// Read the current user from that same context +const user = await getCurrentUser(ctx); +const attributes = await fetchUserAttributes(ctx); +``` + + + + +The context argument is optional. `Amplify.configure()` sets a single process-wide context, and calling an API without a leading context falls back to it, exactly as before local contexts existed. Nothing about this changes when you adopt `createAmplifyContext` elsewhere in your app. + +```typescript +import { Amplify } from 'aws-amplify'; +import { signIn, getCurrentUser, fetchUserAttributes } from 'aws-amplify/auth'; +import outputs from './amplify_outputs.json'; + +// Set the global context +Amplify.configure(outputs); + +// Uses the global context, no context argument +await signIn({ username, password }); + +const user = await getCurrentUser(); +const attributes = await fetchUserAttributes(); +``` + + + + + +### Library options are per context + +`createAmplifyContext` takes the same optional `libraryOptions` as `Amplify.configure()` as its second argument, and those options belong to that context alone. A custom token provider, credentials provider, or key-value storage passed here is used only by calls that receive this context: it is never shared with another context or with the global singleton. + +```typescript +const ctx = createAmplifyContext(outputs, { + Auth: { + tokenProvider, + credentialsProvider + } +}); +``` + +If you do not pass any, the context resolves its own per-context Amazon Cognito token and credentials providers backed by `localStorage`. Either way the resulting token store is scoped to the context, which is what lets two contexts hold two signed-in users at the same time. + +## Use multiple isolated contexts + +Because each context is fully isolated, you can hold several at once and they will not share configuration or auth state. Each keeps its own session, so a user signed in through one context is unaffected by the others. + +### Multiple profiles signed in at once + +A user can be signed in to a work profile and a personal profile simultaneously, each with its own configuration and its own independent session. + +```typescript +import { createAmplifyContext } from 'aws-amplify'; +import { signIn, getCurrentUser } from 'aws-amplify/auth'; +import workOutputs from './amplify_work_outputs.json'; +import personalOutputs from './amplify_personal_outputs.json'; + +const workProfile = createAmplifyContext(workOutputs); +const personalProfile = createAmplifyContext(personalOutputs); + +await signIn(workProfile, { username: workEmail, password: workPassword }); +await signIn(personalProfile, { username: personalEmail, password: personalPassword }); + +// Both sessions are live and independent +const workUser = await getCurrentUser(workProfile); +const personalUser = await getCurrentUser(personalProfile); +``` + +### Switching environments + +Point the same running app at different backends, for example alpha, beta, pre-prod, and prod, without reconfiguring Amplify globally. This is useful for internal tools and QA dashboards that compare environments side by side. + +```typescript +import { createAmplifyContext } from 'aws-amplify'; +import { fetchAuthSession } from 'aws-amplify/auth'; +import alphaOutputs from './outputs/alpha.json'; +import betaOutputs from './outputs/beta.json'; +import prodOutputs from './outputs/prod.json'; + +const environments = { + alpha: createAmplifyContext(alphaOutputs), + beta: createAmplifyContext(betaOutputs), + prod: createAmplifyContext(prodOutputs) +}; + +// Select the environment at runtime, no global reconfiguration needed +const ctx = environments[selectedEnvironment]; +const session = await fetchAuthSession(ctx); +``` + + + +**Note:** Before local contexts, switching backends at runtime meant calling `Amplify.configure()` again, which replaced the configuration for the whole app and reset the global auth state. Holding one context per environment avoids that. + + + +## Error handling + +Context resolution surfaces two typed errors with stable `name` and `code` values, so you can catch them uniformly: + +| Error | When it is thrown | +| --- | --- | +| `NoAmplifyContextError` | An API was called without a context AND `Amplify.configure()` has not been called yet (no global context exists), or an explicit `undefined` was passed as the leading context argument. | +| `InvalidAmplifyContextError` | An `AmplifyContext` was passed in a position other than the first argument. | + +```typescript +import { getCurrentUser } from 'aws-amplify/auth'; +import { NoAmplifyContextError } from 'aws-amplify'; + +try { + const user = await getCurrentUser(ctx); +} catch (error) { + if (error instanceof NoAmplifyContextError) { + // No context available: call configure() or create one with createAmplifyContext() + } + throw error; +} +``` + +## Use a local context or a server context? + +Local contexts are for **client-side** code. Server-side runtimes have their own mechanism, and the two are not interchangeable: + +- **Client:** use `createAmplifyContext` from `aws-amplify` and pass the context to the standard category APIs, as shown above. +- **Server:** use `runWithAmplifyServerContext` from `@aws-amplify/adapter-nextjs`, calling the APIs exported from the `aws-amplify//server` sub-paths inside the `operation` callback. See [Server-Side Rendering](/[platform]/frontend/server-side-rendering/). + +The server exports exist to constrain the API surface: only a subset of Amplify APIs is supported server-side, and the `/server` sub-paths are what make that subset explicit. Reaching for a local context on the server would sidestep that boundary and let you call APIs that are not supported in a server runtime. Use the server context instead: it also derives auth state from the incoming request's cookies, which a local context does not do. + + + +Need more than one Amplify configuration, or more than one signed-in identity, at the same time in your client app? A local `AmplifyContext` is the recommended pattern. + + diff --git a/src/pages/[platform]/frontend/server-side-rendering/index.mdx b/src/pages/[platform]/frontend/server-side-rendering/index.mdx index 21ffbac0bc0..46b04609498 100644 --- a/src/pages/[platform]/frontend/server-side-rendering/index.mdx +++ b/src/pages/[platform]/frontend/server-side-rendering/index.mdx @@ -78,6 +78,12 @@ You can use the exported `runWithAmplifyServerContext` function to call Amplify **Tip:** You only need to call the `createServerRunner` function once and reuse the `runWithAmplifyServerContext` function throughout. + + +**Note:** If your **client-side** code needs to hold several Amplify configurations at once, for example one per tenant or per environment, see [Local context](/[platform]/frontend/local-context/). For server-side code, use `runWithAmplifyServerContext` with the `/server` exports as described on this page. + + + From 24728416c90011b59ffa7467ca022a6845ce3378 Mon Sep 17 00:00:00 2001 From: Philipp Andreas Paul Date: Fri, 25 Sep 2026 14:09:41 +0000 Subject: [PATCH 2/4] docs(JS): address review feedback on local context and configuration pages Catch the context errors by name instead of importing them. The classes are internal to @aws-amplify/core (only reachable via core/internals/utils), so importing NoAmplifyContextError from aws-amplify does not compile; a stable name also survives duplicate package copies in one bundle. Correct three claims about the errors: they carry no code field, InvalidAmplifyContextError also fires for a non-context value in the first position, and a leading undefined only throws when another argument follows it. Spell the native required-fields tables with the real amplify_outputs.json keys (aws_region, user_pool_id, default_authorization_type, ...) rather than camelCase, since the heading says these are fields of the JSON file; each table notes that the typed builders take the same fields in camelCase. Pin the type and schema links to aws-amplify@6.22.0 and @aws-amplify/client-config@1.11.1 so their content cannot move underneath the docs. Keep the runtime environment-switching explanation on the local context page only; connect-to-existing-resources now shows how to build the per-environment configurations and links there for what a context isolates. Wrap the ResourcesConfig note after the Notifications tables in the JS InlineFilter; it sat where Swift, Android and Flutter readers saw it. Use the Callout info prop, which exists, instead of informational, which is ignored. And drop "simply" per the styleguide. --- .../connect-to-existing-resources/index.mdx | 81 +++++++++---------- .../frontend/local-context/index.mdx | 13 +-- 2 files changed, 47 insertions(+), 47 deletions(-) diff --git a/src/pages/[platform]/frontend/connect-to-existing-resources/index.mdx b/src/pages/[platform]/frontend/connect-to-existing-resources/index.mdx index 2a60e0b1d23..c62313d970c 100644 --- a/src/pages/[platform]/frontend/connect-to-existing-resources/index.mdx +++ b/src/pages/[platform]/frontend/connect-to-existing-resources/index.mdx @@ -587,7 +587,7 @@ Fields of `ResourcesConfig['Auth']`, the object both tabs above build: There is no region field: the region is read from the user pool and identity pool IDs. `Cognito` accepts the user pool fields, the identity pool fields, or both, so an identity-pool-only configuration cannot carry `userPoolId`. -Every other field is optional. See [`AuthConfig`](https://github.com/aws-amplify/amplify-js/blob/main/packages/core/src/singleton/Auth/types.ts) for the full type. +Every other field is optional. See [`AuthConfig`](https://github.com/aws-amplify/amplify-js/blob/aws-amplify%406.22.0/packages/core/src/singleton/Auth/types.ts) for the full type. @@ -597,11 +597,11 @@ Fields of the `auth` block in `amplify_outputs.json`: | Field | Required | Description | |-------|----------|-------------| -| `awsRegion` | Yes | AWS region (e.g. `us-east-1`) | -| `userPoolId` | Yes | Cognito User Pool ID | -| `userPoolClientId` | Yes | Cognito app client ID | +| `aws_region` | Yes | AWS region (e.g. `us-east-1`) | +| `user_pool_id` | Yes | Cognito User Pool ID | +| `user_pool_client_id` | Yes | Cognito app client ID | -Every other field is optional. See the [`amplify_outputs.json` schema](https://github.com/aws-amplify/amplify-backend/blob/main/packages/client-config/src/client-config-schema/schema_v1.5.json) for the full shape. +These are the JSON keys. The typed builders above take the same fields in camelCase (`aws_region` is `awsRegion`). Every other field is optional. See the [`amplify_outputs.json` schema](https://github.com/aws-amplify/amplify-backend/blob/%40aws-amplify%2Fclient-config%401.11.1/packages/client-config/src/client-config-schema/schema_v1.5.json) for the full shape. @@ -658,7 +658,7 @@ Amplify.configure({ - + In a `ResourcesConfig` object the AppSync API lives under `API.GraphQL`, and `defaultAuthMode` takes the client-side value, one of `apiKey`, `userPool`, `identityPool`, `oidc`, `lambda`, or `none`, rather than the `API_KEY` style used in `amplify_outputs.json`. @@ -739,7 +739,7 @@ Fields of `ResourcesConfig['API']`, the object both tabs above build: | `GraphQL.apiKey` | With `apiKey` auth | AppSync API key | | `GraphQL.region` | With `identityPool` auth | Region used to sign the request | -Every other field is optional. See [`APIConfig`](https://github.com/aws-amplify/amplify-js/blob/main/packages/core/src/singleton/API/types.ts) for the full type. +Every other field is optional. See [`APIConfig`](https://github.com/aws-amplify/amplify-js/blob/aws-amplify%406.22.0/packages/core/src/singleton/API/types.ts) for the full type. @@ -749,13 +749,13 @@ Fields of the `data` block in `amplify_outputs.json`: | Field | Required | Description | |-------|----------|-------------| -| `awsRegion` | Yes | AWS region | +| `aws_region` | Yes | AWS region | | `url` | Yes | AppSync GraphQL endpoint URL | -| `defaultAuthorizationType` | Yes | Default auth mode: `AMAZON_COGNITO_USER_POOLS`, `API_KEY`, `AWS_IAM`, `AWS_LAMBDA`, or `OPENID_CONNECT` | -| `authorizationTypes` | Yes | Every auth mode the API accepts, from the same list | -| `apiKey` | With `API_KEY` auth | AppSync API key | +| `default_authorization_type` | Yes | Default auth mode: `AMAZON_COGNITO_USER_POOLS`, `API_KEY`, `AWS_IAM`, `AWS_LAMBDA`, or `OPENID_CONNECT` | +| `authorization_types` | Yes | Every auth mode the API accepts, from the same list | +| `api_key` | With `API_KEY` auth | AppSync API key | -Every other field is optional. See the [`amplify_outputs.json` schema](https://github.com/aws-amplify/amplify-backend/blob/main/packages/client-config/src/client-config-schema/schema_v1.5.json) for the full shape. +These are the JSON keys. The typed builders above take the same fields in camelCase (`aws_region` is `awsRegion`). Every other field is optional. See the [`amplify_outputs.json` schema](https://github.com/aws-amplify/amplify-backend/blob/%40aws-amplify%2Fclient-config%401.11.1/packages/client-config/src/client-config-schema/schema_v1.5.json) for the full shape. @@ -982,7 +982,7 @@ final config = AmplifyOutputs( - + Storage requires Auth (Cognito Identity Pool) for authorization. Always configure Auth alongside Storage. @@ -1000,7 +1000,7 @@ Fields of `ResourcesConfig['Storage']`, the object both tabs above build: | `S3.region` | For the default bucket | Region of that bucket | | `S3.buckets[name].bucketName`, `S3.buckets[name].region` | With additional buckets | Each extra bucket is keyed by the friendly name you pass to the Storage APIs | -Every other field is optional. See [`StorageConfig`](https://github.com/aws-amplify/amplify-js/blob/main/packages/core/src/singleton/Storage/types.ts) for the full type. +Every other field is optional. See [`StorageConfig`](https://github.com/aws-amplify/amplify-js/blob/aws-amplify%406.22.0/packages/core/src/singleton/Storage/types.ts) for the full type. @@ -1010,11 +1010,11 @@ Fields of the `storage` block in `amplify_outputs.json`: | Field | Required | Description | |-------|----------|-------------| -| `awsRegion` | Yes | AWS region | -| `bucketName` | Yes | Default S3 bucket name | -| `buckets[].name`, `buckets[].bucketName`, `buckets[].awsRegion` | With additional buckets | All three are required on every entry | +| `aws_region` | Yes | AWS region | +| `bucket_name` | Yes | Default S3 bucket name | +| `buckets[].name`, `buckets[].bucket_name`, `buckets[].aws_region` | With additional buckets | All three are required on every entry | -Every other field is optional. See the [`amplify_outputs.json` schema](https://github.com/aws-amplify/amplify-backend/blob/main/packages/client-config/src/client-config-schema/schema_v1.5.json) for the full shape. +These are the JSON keys. The typed builders above take the same fields in camelCase (`aws_region` is `awsRegion`). Every other field is optional. See the [`amplify_outputs.json` schema](https://github.com/aws-amplify/amplify-backend/blob/%40aws-amplify%2Fclient-config%401.11.1/packages/client-config/src/client-config-schema/schema_v1.5.json) for the full shape. @@ -1132,7 +1132,7 @@ Fields of `ResourcesConfig['Analytics']`, the object both tabs above build: | `Pinpoint.appId` | Yes | Pinpoint application (project) ID | | `Pinpoint.region` | Yes | Region of the Pinpoint project | -Every other field is optional. See [`AnalyticsConfig`](https://github.com/aws-amplify/amplify-js/blob/main/packages/core/src/singleton/Analytics/types.ts) for the full type. +Every other field is optional. See [`AnalyticsConfig`](https://github.com/aws-amplify/amplify-js/blob/aws-amplify%406.22.0/packages/core/src/singleton/Analytics/types.ts) for the full type. @@ -1142,10 +1142,10 @@ Fields of the `analytics.amazon_pinpoint` block in `amplify_outputs.json`: | Field | Required | Description | |-------|----------|-------------| -| `awsRegion` | Yes | AWS region of the Pinpoint project | -| `appId` | Yes | Pinpoint application (project) ID | +| `aws_region` | Yes | AWS region of the Pinpoint project | +| `app_id` | Yes | Pinpoint application (project) ID | -Every other field is optional. See the [`amplify_outputs.json` schema](https://github.com/aws-amplify/amplify-backend/blob/main/packages/client-config/src/client-config-schema/schema_v1.5.json) for the full shape. +These are the JSON keys. The typed builders above take the same fields in camelCase (`aws_region` is `awsRegion`). Every other field is optional. See the [`amplify_outputs.json` schema](https://github.com/aws-amplify/amplify-backend/blob/%40aws-amplify%2Fclient-config%401.11.1/packages/client-config/src/client-config-schema/schema_v1.5.json) for the full shape. @@ -1291,7 +1291,7 @@ Fields of `ResourcesConfig['Geo']`, the object both tabs above build: | `LocationService.searchIndices.items`, `LocationService.searchIndices.default` | With `searchIndices` | Place index names, plus the default index | | `LocationService.geofenceCollections.items`, `LocationService.geofenceCollections.default` | With `geofenceCollections` | Collection names, plus the default collection | -Every other field is optional. See [`GeoConfig`](https://github.com/aws-amplify/amplify-js/blob/main/packages/core/src/singleton/Geo/types.ts) for the full type. +Every other field is optional. See [`GeoConfig`](https://github.com/aws-amplify/amplify-js/blob/aws-amplify%406.22.0/packages/core/src/singleton/Geo/types.ts) for the full type. @@ -1301,12 +1301,12 @@ Fields of the `geo` block in `amplify_outputs.json`: | Field | Required | Description | |-------|----------|-------------| -| `awsRegion` | Yes | AWS region of the Location Service resources | +| `aws_region` | Yes | AWS region of the Location Service resources | | `maps.items`, `maps.default` | With `maps` | Maps keyed by name, plus the default map name | -| `searchIndices.items`, `searchIndices.default` | With `searchIndices` | Place index names, plus the default index | -| `geofenceCollections.items`, `geofenceCollections.default` | With `geofenceCollections` | Collection names, plus the default collection | +| `search_indices.items`, `search_indices.default` | With `search_indices` | Place index names, plus the default index | +| `geofence_collections.items`, `geofence_collections.default` | With `geofence_collections` | Collection names, plus the default collection | -Every other field is optional. See the [`amplify_outputs.json` schema](https://github.com/aws-amplify/amplify-backend/blob/main/packages/client-config/src/client-config-schema/schema_v1.5.json) for the full shape. +These are the JSON keys. The typed builders above take the same fields in camelCase (`aws_region` is `awsRegion`). Every other field is optional. See the [`amplify_outputs.json` schema](https://github.com/aws-amplify/amplify-backend/blob/%40aws-amplify%2Fclient-config%401.11.1/packages/client-config/src/client-config-schema/schema_v1.5.json) for the full shape. @@ -1429,7 +1429,7 @@ Fields of `ResourcesConfig['Notifications']`, the object both tabs above build. | `PushNotification.CustomerProfiles.endpoint`, `PushNotification.CustomerProfiles.region` | For Amazon Connect push | Amazon Connect Customer Profiles endpoint backing push device registration | | `InAppMessaging.Pinpoint.appId`, `InAppMessaging.Pinpoint.region` | For in-app messaging | Pinpoint project backing in-app messages | -Every other field is optional. See [`NotificationsConfig`](https://github.com/aws-amplify/amplify-js/blob/main/packages/core/src/singleton/Notifications/types.ts) for the full type. +Every other field is optional. See [`NotificationsConfig`](https://github.com/aws-amplify/amplify-js/blob/aws-amplify%406.22.0/packages/core/src/singleton/Notifications/types.ts) for the full type. @@ -1439,18 +1439,22 @@ Fields of the `notifications` block in `amplify_outputs.json`: | Field | Required | Description | |-------|----------|-------------| -| `awsRegion` | For Pinpoint | AWS region of the Pinpoint project | -| `amazonPinpointAppId` | For Pinpoint | Pinpoint application ID | +| `aws_region` | For Pinpoint | AWS region of the Pinpoint project | +| `amazon_pinpoint_app_id` | For Pinpoint | Pinpoint application ID | | `channels` | For Pinpoint | Channels to enable: `APNS`, `FCM`, `IN_APP_MESSAGING`, `EMAIL`, or `SMS`. At least one entry, no duplicates | -| `amazonConnect.awsRegion`, `amazonConnect.endpoint` | With Amazon Connect | Customer Profiles endpoint used for push device registration | +| `amazon_connect.aws_region`, `amazon_connect.endpoint` | With Amazon Connect | Customer Profiles endpoint used for push device registration | -No field is required on its own: a Pinpoint setup needs the region, the app ID, and at least one channel, while an Amazon Connect setup needs only `amazonConnect`. +No field is required on its own: a Pinpoint setup needs the region, the app ID, and at least one channel, while an Amazon Connect setup needs only `amazon_connect`. -Every other field is optional. See the [`amplify_outputs.json` schema](https://github.com/aws-amplify/amplify-backend/blob/main/packages/client-config/src/client-config-schema/schema_v1.5.json) for the full shape. +These are the JSON keys. The typed builders above take the same fields in camelCase (`aws_region` is `awsRegion`). Every other field is optional. See the [`amplify_outputs.json` schema](https://github.com/aws-amplify/amplify-backend/blob/%40aws-amplify%2Fclient-config%401.11.1/packages/client-config/src/client-config-schema/schema_v1.5.json) for the full shape. -In a `ResourcesConfig` object there is no `channels` list: which channels are active follows from the providers you configure, `PushNotification` and `InAppMessaging`. `amazonConnect` becomes `Notifications.PushNotification.CustomerProfiles` with `endpoint` and `region`. + + +In a `ResourcesConfig` object there is no `channels` list: which channels are active follows from the providers you configure, `PushNotification` and `InAppMessaging`. `amazon_connect` becomes `Notifications.PushNotification.CustomerProfiles` with `endpoint` and `region`. + + ## Multi-category configuration @@ -1782,23 +1786,18 @@ Amplify.configure(outputs); ### Several environments at the same time -`Amplify.configure()` sets one process-wide configuration, so selecting an environment this way means the whole app moves with it, and calling `configure()` again later resets global auth state. When you need more than one environment live at once, create a [local context](/[platform]/frontend/local-context/) per configuration and pass it to the category APIs instead: +`Amplify.configure()` sets one process-wide configuration, so selecting an environment this way means the whole app moves with it. To keep more than one environment live at once, pass each configuration to `createAmplifyContext()` instead of to `configure()`, then hand the resulting context to the category APIs: ```typescript import { createAmplifyContext } from 'aws-amplify'; -import { fetchAuthSession } from 'aws-amplify/auth'; const environments = { dev: createAmplifyContext(withUserPool('us-east-1_dev123')), prod: createAmplifyContext(withUserPool('us-east-1_prod789')) }; - -// Each context keeps its own configuration and its own session -const devSession = await fetchAuthSession(environments.dev); -const prodSession = await fetchAuthSession(environments.prod); ``` -Each context is isolated, so a user signed in through one is unaffected by the others, which is what makes side-by-side environment comparison, tenant switching, and holding two profiles signed in at once possible. [Local contexts](/[platform]/frontend/local-context/) are a client-side API; for server-side runtimes, use `runWithAmplifyServerContext` with the `/server` exports as described under [Server-Side Rendering](/[platform]/frontend/server-side-rendering/). +See [Local context](/[platform]/frontend/local-context/) for what a context isolates, how to use one, and why it is a client-side API. diff --git a/src/pages/[platform]/frontend/local-context/index.mdx b/src/pages/[platform]/frontend/local-context/index.mdx index 28d54a9089e..53f5bb0870c 100644 --- a/src/pages/[platform]/frontend/local-context/index.mdx +++ b/src/pages/[platform]/frontend/local-context/index.mdx @@ -53,7 +53,7 @@ Reach for `createAmplifyContext` whenever a single global configuration is not e -Import `createAmplifyContext` from `aws-amplify`, pass your backend outputs to create the context, then hand that context to any category API as its **first** positional argument. Unlike `Amplify.configure()`, creating a context does **not** set a global context and does **not** dispatch any Hub events: it simply returns a new, isolated context object, ready to use immediately. +Import `createAmplifyContext` from `aws-amplify`, pass your backend outputs to create the context, then hand that context to any category API as its **first** positional argument. Unlike `Amplify.configure()`, creating a context does **not** set a global context and does **not** dispatch any Hub events: it returns a new, isolated context object, ready to use immediately. ```typescript import { createAmplifyContext } from 'aws-amplify'; @@ -165,21 +165,22 @@ const session = await fetchAuthSession(ctx); ## Error handling -Context resolution surfaces two typed errors with stable `name` and `code` values, so you can catch them uniformly: +Context resolution surfaces two typed errors with stable `name` values, so you can catch them uniformly: | Error | When it is thrown | | --- | --- | -| `NoAmplifyContextError` | An API was called without a context AND `Amplify.configure()` has not been called yet (no global context exists), or an explicit `undefined` was passed as the leading context argument. | -| `InvalidAmplifyContextError` | An `AmplifyContext` was passed in a position other than the first argument. | +| `NoAmplifyContextError` | An API was called without a context AND `Amplify.configure()` has not been called yet (no global context exists), or `undefined` was passed as the leading context argument followed by other arguments. | +| `InvalidAmplifyContextError` | A value that is not an `AmplifyContext` was passed as the first argument, or an `AmplifyContext` was passed in a position other than the first argument. | + +Catch them by `name`. The error classes are internal, so there is nothing to import, and a stable name keeps working even when two copies of a package end up in the same bundle: ```typescript import { getCurrentUser } from 'aws-amplify/auth'; -import { NoAmplifyContextError } from 'aws-amplify'; try { const user = await getCurrentUser(ctx); } catch (error) { - if (error instanceof NoAmplifyContextError) { + if (error instanceof Error && error.name === 'NoAmplifyContextError') { // No context available: call configure() or create one with createAmplifyContext() } throw error; From 64ef5ba7ed6a60e7a5227046daaf20a3e9365601 Mon Sep 17 00:00:00 2001 From: Philipp Andreas Paul Date: Mon, 28 Sep 2026 08:41:37 +0000 Subject: [PATCH 3/4] docs(amplify-libraries): spell the native field tables as the typed configuration Revert the required-fields tables on the Swift, Android and Flutter routes to the camelCase names their typed configuration actually takes (awsRegion, userPoolId, defaultAuthorizationType, ...) and drop the "fields of the block in amplify_outputs.json" heading above each one. The tables sit under code examples that build AmplifyOutputsData, so they document that object rather than the JSON file, the same way the JS tables document ResourcesConfig[K]. Prefix the Analytics rows with amazonPinpoint, since the removed heading was what carried that nesting and the example above the table nests the same way. Drop the amazonConnect row: schema v1.5 carries amazon_connect, but AmplifyOutputsData.Notifications declares only awsRegion, amazonPinpointAppId and channels, so there is no such field to configure on these platforms. State defaultAuthorizationType's values in prose, because each platform spells them as its own enum (.apiKey in Swift and Dart, API_KEY in Kotlin) and no single literal list is correct for all three. --- .../connect-to-existing-resources/index.mdx | 65 ++++++++----------- 1 file changed, 26 insertions(+), 39 deletions(-) diff --git a/src/pages/[platform]/frontend/connect-to-existing-resources/index.mdx b/src/pages/[platform]/frontend/connect-to-existing-resources/index.mdx index c62313d970c..219bdf0de47 100644 --- a/src/pages/[platform]/frontend/connect-to-existing-resources/index.mdx +++ b/src/pages/[platform]/frontend/connect-to-existing-resources/index.mdx @@ -593,15 +593,13 @@ Every other field is optional. See [`AuthConfig`](https://github.com/aws-amplify -Fields of the `auth` block in `amplify_outputs.json`: - | Field | Required | Description | |-------|----------|-------------| -| `aws_region` | Yes | AWS region (e.g. `us-east-1`) | -| `user_pool_id` | Yes | Cognito User Pool ID | -| `user_pool_client_id` | Yes | Cognito app client ID | +| `awsRegion` | Yes | AWS region (e.g. `us-east-1`) | +| `userPoolId` | Yes | Cognito User Pool ID | +| `userPoolClientId` | Yes | Cognito app client ID | -These are the JSON keys. The typed builders above take the same fields in camelCase (`aws_region` is `awsRegion`). Every other field is optional. See the [`amplify_outputs.json` schema](https://github.com/aws-amplify/amplify-backend/blob/%40aws-amplify%2Fclient-config%401.11.1/packages/client-config/src/client-config-schema/schema_v1.5.json) for the full shape. +Every other field is optional. See the [`amplify_outputs.json` schema](https://github.com/aws-amplify/amplify-backend/blob/%40aws-amplify%2Fclient-config%401.11.1/packages/client-config/src/client-config-schema/schema_v1.5.json) for the full shape. @@ -745,17 +743,15 @@ Every other field is optional. See [`APIConfig`](https://github.com/aws-amplify/ -Fields of the `data` block in `amplify_outputs.json`: - | Field | Required | Description | |-------|----------|-------------| -| `aws_region` | Yes | AWS region | +| `awsRegion` | Yes | AWS region | | `url` | Yes | AppSync GraphQL endpoint URL | -| `default_authorization_type` | Yes | Default auth mode: `AMAZON_COGNITO_USER_POOLS`, `API_KEY`, `AWS_IAM`, `AWS_LAMBDA`, or `OPENID_CONNECT` | -| `authorization_types` | Yes | Every auth mode the API accepts, from the same list | -| `api_key` | With `API_KEY` auth | AppSync API key | +| `defaultAuthorizationType` | Yes | Default auth mode: API key, Cognito user pools, IAM, Lambda, or OIDC | +| `authorizationTypes` | Yes | Every auth mode the API accepts, from the same list | +| `apiKey` | With API key auth | AppSync API key | -These are the JSON keys. The typed builders above take the same fields in camelCase (`aws_region` is `awsRegion`). Every other field is optional. See the [`amplify_outputs.json` schema](https://github.com/aws-amplify/amplify-backend/blob/%40aws-amplify%2Fclient-config%401.11.1/packages/client-config/src/client-config-schema/schema_v1.5.json) for the full shape. +Every other field is optional. See the [`amplify_outputs.json` schema](https://github.com/aws-amplify/amplify-backend/blob/%40aws-amplify%2Fclient-config%401.11.1/packages/client-config/src/client-config-schema/schema_v1.5.json) for the full shape. @@ -1006,15 +1002,13 @@ Every other field is optional. See [`StorageConfig`](https://github.com/aws-ampl -Fields of the `storage` block in `amplify_outputs.json`: - | Field | Required | Description | |-------|----------|-------------| -| `aws_region` | Yes | AWS region | -| `bucket_name` | Yes | Default S3 bucket name | -| `buckets[].name`, `buckets[].bucket_name`, `buckets[].aws_region` | With additional buckets | All three are required on every entry | +| `awsRegion` | Yes | AWS region | +| `bucketName` | Yes | Default S3 bucket name | +| `buckets[].name`, `buckets[].bucketName`, `buckets[].awsRegion` | With additional buckets | All three are required on every entry | -These are the JSON keys. The typed builders above take the same fields in camelCase (`aws_region` is `awsRegion`). Every other field is optional. See the [`amplify_outputs.json` schema](https://github.com/aws-amplify/amplify-backend/blob/%40aws-amplify%2Fclient-config%401.11.1/packages/client-config/src/client-config-schema/schema_v1.5.json) for the full shape. +Every other field is optional. See the [`amplify_outputs.json` schema](https://github.com/aws-amplify/amplify-backend/blob/%40aws-amplify%2Fclient-config%401.11.1/packages/client-config/src/client-config-schema/schema_v1.5.json) for the full shape. @@ -1138,14 +1132,12 @@ Every other field is optional. See [`AnalyticsConfig`](https://github.com/aws-am -Fields of the `analytics.amazon_pinpoint` block in `amplify_outputs.json`: - | Field | Required | Description | |-------|----------|-------------| -| `aws_region` | Yes | AWS region of the Pinpoint project | -| `app_id` | Yes | Pinpoint application (project) ID | +| `amazonPinpoint.awsRegion` | Yes | AWS region of the Pinpoint project | +| `amazonPinpoint.appId` | Yes | Pinpoint application (project) ID | -These are the JSON keys. The typed builders above take the same fields in camelCase (`aws_region` is `awsRegion`). Every other field is optional. See the [`amplify_outputs.json` schema](https://github.com/aws-amplify/amplify-backend/blob/%40aws-amplify%2Fclient-config%401.11.1/packages/client-config/src/client-config-schema/schema_v1.5.json) for the full shape. +Every other field is optional. See the [`amplify_outputs.json` schema](https://github.com/aws-amplify/amplify-backend/blob/%40aws-amplify%2Fclient-config%401.11.1/packages/client-config/src/client-config-schema/schema_v1.5.json) for the full shape. @@ -1297,16 +1289,14 @@ Every other field is optional. See [`GeoConfig`](https://github.com/aws-amplify/ -Fields of the `geo` block in `amplify_outputs.json`: - | Field | Required | Description | |-------|----------|-------------| -| `aws_region` | Yes | AWS region of the Location Service resources | +| `awsRegion` | Yes | AWS region of the Location Service resources | | `maps.items`, `maps.default` | With `maps` | Maps keyed by name, plus the default map name | -| `search_indices.items`, `search_indices.default` | With `search_indices` | Place index names, plus the default index | -| `geofence_collections.items`, `geofence_collections.default` | With `geofence_collections` | Collection names, plus the default collection | +| `searchIndices.items`, `searchIndices.default` | With `searchIndices` | Place index names, plus the default index | +| `geofenceCollections.items`, `geofenceCollections.default` | With `geofenceCollections` | Collection names, plus the default collection | -These are the JSON keys. The typed builders above take the same fields in camelCase (`aws_region` is `awsRegion`). Every other field is optional. See the [`amplify_outputs.json` schema](https://github.com/aws-amplify/amplify-backend/blob/%40aws-amplify%2Fclient-config%401.11.1/packages/client-config/src/client-config-schema/schema_v1.5.json) for the full shape. +Every other field is optional. See the [`amplify_outputs.json` schema](https://github.com/aws-amplify/amplify-backend/blob/%40aws-amplify%2Fclient-config%401.11.1/packages/client-config/src/client-config-schema/schema_v1.5.json) for the full shape. @@ -1435,24 +1425,21 @@ Every other field is optional. See [`NotificationsConfig`](https://github.com/aw -Fields of the `notifications` block in `amplify_outputs.json`: - | Field | Required | Description | |-------|----------|-------------| -| `aws_region` | For Pinpoint | AWS region of the Pinpoint project | -| `amazon_pinpoint_app_id` | For Pinpoint | Pinpoint application ID | -| `channels` | For Pinpoint | Channels to enable: `APNS`, `FCM`, `IN_APP_MESSAGING`, `EMAIL`, or `SMS`. At least one entry, no duplicates | -| `amazon_connect.aws_region`, `amazon_connect.endpoint` | With Amazon Connect | Customer Profiles endpoint used for push device registration | +| `awsRegion` | For Pinpoint | AWS region of the Pinpoint project | +| `amazonPinpointAppId` | For Pinpoint | Pinpoint application ID | +| `channels` | For Pinpoint | Channels to enable: APNS, FCM, in-app messaging, email, or SMS. At least one entry, no duplicates | -No field is required on its own: a Pinpoint setup needs the region, the app ID, and at least one channel, while an Amazon Connect setup needs only `amazon_connect`. +A Pinpoint setup needs all three: the region, the app ID, and at least one channel. -These are the JSON keys. The typed builders above take the same fields in camelCase (`aws_region` is `awsRegion`). Every other field is optional. See the [`amplify_outputs.json` schema](https://github.com/aws-amplify/amplify-backend/blob/%40aws-amplify%2Fclient-config%401.11.1/packages/client-config/src/client-config-schema/schema_v1.5.json) for the full shape. +Every other field is optional. See the [`amplify_outputs.json` schema](https://github.com/aws-amplify/amplify-backend/blob/%40aws-amplify%2Fclient-config%401.11.1/packages/client-config/src/client-config-schema/schema_v1.5.json) for the full shape. -In a `ResourcesConfig` object there is no `channels` list: which channels are active follows from the providers you configure, `PushNotification` and `InAppMessaging`. `amazon_connect` becomes `Notifications.PushNotification.CustomerProfiles` with `endpoint` and `region`. +In a `ResourcesConfig` object there is no `channels` list: which channels are active follows from the providers you configure, `PushNotification` and `InAppMessaging`. `amazonConnect` becomes `Notifications.PushNotification.CustomerProfiles` with `endpoint` and `region`. From d785d21a26585d3e46cdc58df781399070272f6e Mon Sep 17 00:00:00 2001 From: Philipp Andreas Paul Date: Mon, 28 Sep 2026 10:03:09 +0000 Subject: [PATCH 4/4] docs(amplify-libraries): restore the Amazon Connect row for Android 64ef5ba7e dropped the amazonConnect row from the shared native Notifications table on the grounds that AmplifyOutputsData.Notifications declares only awsRegion, amazonPinpointAppId and channels. That holds for amplify-swift and amplify-flutter but not for amplify-android, whose Notifications carries amazonConnect: AmazonConnect? with required awsRegion and endpoint (core/src/main/java/com/amplifyframework/core/configuration/AmplifyOutputsData.kt), so Android readers lost a field they can configure. Split the table: Swift and Flutter keep the three Pinpoint rows, Android gets a fourth amazonConnect row and lead-in wording saying either provider, or both, can be configured. Name the outputs-file key in the JS note as well. It said amazonConnect, which matched no name a JS reader sees now that the native row is platform-filtered; the file's key is amazon_connect and that is what parseNotifications maps onto Notifications.PushNotification.CustomerProfiles. --- .../connect-to-existing-resources/index.mdx | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/pages/[platform]/frontend/connect-to-existing-resources/index.mdx b/src/pages/[platform]/frontend/connect-to-existing-resources/index.mdx index 219bdf0de47..a29d35b0d2b 100644 --- a/src/pages/[platform]/frontend/connect-to-existing-resources/index.mdx +++ b/src/pages/[platform]/frontend/connect-to-existing-resources/index.mdx @@ -1423,7 +1423,7 @@ Every other field is optional. See [`NotificationsConfig`](https://github.com/aw - + | Field | Required | Description | |-------|----------|-------------| @@ -1437,9 +1437,26 @@ Every other field is optional. See the [`amplify_outputs.json` schema](https://g + + +Configure either a Pinpoint project or an Amazon Connect endpoint, or both: + +| Field | Required | Description | +|-------|----------|-------------| +| `awsRegion` | For Pinpoint | AWS region of the Pinpoint project | +| `amazonPinpointAppId` | For Pinpoint | Pinpoint application ID | +| `channels` | For Pinpoint | Channels to enable: APNS, FCM, in-app messaging, email, or SMS. At least one entry, no duplicates | +| `amazonConnect.awsRegion`, `amazonConnect.endpoint` | For Amazon Connect | Amazon Connect Customer Profiles endpoint backing push device registration. Both are required on the entry | + +A Pinpoint setup needs all three Pinpoint fields: the region, the app ID, and at least one channel. + +Every other field is optional. See the [`amplify_outputs.json` schema](https://github.com/aws-amplify/amplify-backend/blob/%40aws-amplify%2Fclient-config%401.11.1/packages/client-config/src/client-config-schema/schema_v1.5.json) for the full shape. + + + -In a `ResourcesConfig` object there is no `channels` list: which channels are active follows from the providers you configure, `PushNotification` and `InAppMessaging`. `amazonConnect` becomes `Notifications.PushNotification.CustomerProfiles` with `endpoint` and `region`. +In a `ResourcesConfig` object there is no `channels` list: which channels are active follows from the providers you configure, `PushNotification` and `InAppMessaging`. The `amazon_connect` block in `amplify_outputs.json` becomes `Notifications.PushNotification.CustomerProfiles` with `endpoint` and `region`.