diff --git a/packages/@aws-cdk/aws-amplify/README.md b/packages/@aws-cdk/aws-amplify/README.md index 9c1b33b01d44a..f6e9b17e71627 100644 --- a/packages/@aws-cdk/aws-amplify/README.md +++ b/packages/@aws-cdk/aws-amplify/README.md @@ -83,6 +83,16 @@ amplifyApp.addCustomRule({ }); ``` +When working with a single page application (SPA), use the +`CustomRule.SINGLE_PAGE_APPLICATION_REDIRECT` to set up a 200 +rewrite for all files to `index.html` except for the following +file extensions: css, gif, ico, jpg, js, png, txt, svg, woff, +ttf, map, json, webmanifest. + +```ts +mySinglePageApp.addCustomRule(amplify.CustomRule.SINGLE_PAGE_APPLICATION_REDIRECT); +``` + Add a domain and map sub domains to branches: ```ts const domain = amplifyApp.addDomain('example.com'); diff --git a/packages/@aws-cdk/aws-amplify/lib/app.ts b/packages/@aws-cdk/aws-amplify/lib/app.ts index 3448ecbc11d79..483bbbb58d6c7 100644 --- a/packages/@aws-cdk/aws-amplify/lib/app.ts +++ b/packages/@aws-cdk/aws-amplify/lib/app.ts @@ -375,22 +375,28 @@ export enum RedirectStatus { } /** - * Custom rewrite/redirect rule for an Amplify App. + * Options for a custom rewrite/redirect rule for an Amplify App. */ -export interface CustomRule { +export interface CustomRuleOptions { /** * The source pattern for a URL rewrite or redirect rule. + * + * @see https://docs.aws.amazon.com/amplify/latest/userguide/redirects.html */ readonly source: string; /** * The target pattern for a URL rewrite or redirect rule. + * + * @see https://docs.aws.amazon.com/amplify/latest/userguide/redirects.html */ readonly target: string /** * The status code for a URL rewrite or redirect rule. * + * @see https://docs.aws.amazon.com/amplify/latest/userguide/redirects.html + * * @default PERMANENT_REDIRECT */ readonly status?: RedirectStatus; @@ -398,7 +404,65 @@ export interface CustomRule { /** * The condition for a URL rewrite or redirect rule, e.g. country code. * + * @see https://docs.aws.amazon.com/amplify/latest/userguide/redirects.html + * * @default - no condition */ readonly condition?: string; } + +/** + * Custom rewrite/redirect rule for an Amplify App. + * + * @see https://docs.aws.amazon.com/amplify/latest/userguide/redirects.html + */ +export class CustomRule { + /** + * Sets up a 200 rewrite for all paths to `index.html` except for path + * containing a file extension. + */ + public static readonly SINGLE_PAGE_APPLICATION_REDIRECT = new CustomRule({ + source: '', + target: '/index.html', + status: RedirectStatus.REWRITE, + }); + + /** + * The source pattern for a URL rewrite or redirect rule. + * + * @see https://docs.aws.amazon.com/amplify/latest/userguide/redirects.html + */ + public readonly source: string; + + /** + * The target pattern for a URL rewrite or redirect rule. + * + * @see https://docs.aws.amazon.com/amplify/latest/userguide/redirects.html + */ + public readonly target: string; + + /** + * The status code for a URL rewrite or redirect rule. + * + * @see https://docs.aws.amazon.com/amplify/latest/userguide/redirects.html + * + * @default PERMANENT_REDIRECT + */ + public readonly status?: RedirectStatus; + + /** + * The condition for a URL rewrite or redirect rule, e.g. country code. + * + * @see https://docs.aws.amazon.com/amplify/latest/userguide/redirects.html + * + * @default - no condition + */ + public readonly condition?: string; + + constructor(options: CustomRuleOptions) { + this.source = options.source; + this.target = options.target; + this.status = options.status; + this.condition = options.condition; + } +} diff --git a/packages/@aws-cdk/aws-amplify/test/app.test.ts b/packages/@aws-cdk/aws-amplify/test/app.test.ts index be648a160798e..b5c9a3b3a7942 100644 --- a/packages/@aws-cdk/aws-amplify/test/app.test.ts +++ b/packages/@aws-cdk/aws-amplify/test/app.test.ts @@ -261,6 +261,29 @@ test('with custom rules', () => { }); }); +test('with SPA redirect', () => { + // WHEN + new amplify.App(stack, 'App', { + sourceCodeProvider: new amplify.GitHubSourceCodeProvider({ + owner: 'aws', + repository: 'aws-cdk', + oauthToken: SecretValue.plainText('secret'), + }), + customRules: [amplify.CustomRule.SINGLE_PAGE_APPLICATION_REDIRECT], + }); + + // THEN + expect(stack).toHaveResource('AWS::Amplify::App', { + CustomRules: [ + { + Source: '', + Status: '200', + Target: '/index.html', + }, + ], + }); +}); + test('with auto branch creation', () => { // WHEN const app = new amplify.App(stack, 'App', {