Skip to main content

Amplify Hosting

The Next.js 16 frontend is hosted on AWS Amplify, which provides fully managed SSR hosting, automatic deployments from Git, and built-in CDN distribution. Amplify handles provisioning, scaling, and SSL certificate management without any EC2 instances or Docker containers.

App Configuration

PropertyValue
App IDd2x4yh9us5ctu1
Regioneu-north-1 (Stockholm)
FrameworkNext.js 16 with SSR
RepositoryAiQlickProject/aiqlick-frontend
Build modeServer-side rendering (not static export)

The app is configured to build and deploy server-rendered Next.js pages, API routes, and static assets. Amplify's compute layer runs the Next.js server for SSR pages, while static assets are served through the built-in CDN.

Branch-to-Environment Mapping

Amplify maps Git branches to deployment stages. Each branch has its own build configuration, environment variables, and custom domain.

BranchStageDomainBackend APIAI Service
devDEVELOPMENTdev.aiqlick.comapi-dev.aiqlick.comai-dev.aiqlick.com
mainPRODUCTIONwww.aiqlick.comapi.aiqlick.comai.aiqlick.com

Pushes to either branch trigger an automatic build and deploy. No manual intervention is required.

tip

The dev branch is the default working branch. All feature work is merged into dev first, and production deployments happen via pull request from dev to main.

Custom Domain

The root domain aiqlick.com is managed on one.com. DNS records are configured as CNAME entries pointing to Amplify's generated domain.

SubdomainPoints ToBranch
www.aiqlick.comAmplify PRODUCTIONmain
dev.aiqlick.comAmplify DEVELOPMENTdev

Amplify provisions and automatically renews SSL certificates for both subdomains. Certificate validation is handled via CNAME DNS records that were set up during initial domain configuration on one.com.

note

Amplify does not host the root domain aiqlick.com directly. The www subdomain is used for production. A redirect from aiqlick.com to www.aiqlick.com is configured at the DNS level.

Build Settings

Build Specification

Amplify uses a build specification (either amplify.yml in the repository root or the default buildSpec configured in the Amplify console) to define the build steps:

version: 1
frontend:
phases:
preBuild:
commands:
- npm install
build:
commands:
- npm run build
artifacts:
baseDirectory: .next
files:
- '**/*'
cache:
paths:
- node_modules/**/*
- .next/cache/**/*

The build output includes both server-side rendering artifacts and static assets. Amplify routes requests to the correct handler based on whether a page is SSR, ISR, or fully static.

Secrets Injection at Build Time

Each branch has a SECRET_NAME environment variable set in the Amplify console. During the build phase, Amplify fetches the corresponding secret from AWS Secrets Manager and injects the key-value pairs as build-time environment variables.

BranchSECRET_NAME ValueSecrets Manager Path
devaiqlick-backend/developmentaiqlick-backend/development
mainaiqlick-backend/productionaiqlick-backend/production

The build process:

  1. Amplify reads the SECRET_NAME environment variable.
  2. Fetches the secret JSON from Secrets Manager using the Amplify service role.
  3. Parses the JSON and injects each key-value pair as a build environment variable.
  4. The Next.js build picks up NEXT_PUBLIC_* prefixed variables and embeds them in the client bundle.
warning

Frontend secrets are baked into the build at deploy time. After updating a secret in Secrets Manager that affects the frontend, you must trigger a new Amplify build for the changes to take effect. Simply updating the secret is not enough.

Environment Variables

Key environment variables consumed by the Next.js frontend:

VariableDev ValueProd ValuePurpose
NEXT_PUBLIC_API_URLhttps://api-dev.aiqlick.comhttps://api.aiqlick.comBackend GraphQL endpoint (HTTP) — also used for AI gateway HTTP + voice WS path
NEXT_PUBLIC_GRAPHQL_WS_URLwss://api-dev.aiqlick.com/graphqlwss://api.aiqlick.com/graphqlBackend GraphQL subscriptions — also used for AI subscribeAi
NEXT_PUBLIC_APP_URLhttps://dev.aiqlick.comhttps://www.aiqlick.comFrontend base URL for redirects and links

Only variables prefixed with NEXT_PUBLIC_ are exposed to the client-side bundle. Server-only variables (like DATABASE_URL) are available during SSR but never sent to the browser.

note
Phase 3.7 cutover removed the NEXT_PUBLIC_AI_* env vars

The frontend used to talk to background-tasks directly via four NEXT_PUBLIC_AI_* variables (AI_GRAPHQL_URL, AI_GRAPHQL_WS_URL, AI_WS_URL, AI_VOICE_WS_URL). After the cutover, every AI call routes through the NestJS gateway over the same NEXT_PUBLIC_API_URL / NEXT_PUBLIC_GRAPHQL_WS_URL endpoints — there is no longer a separate background-tasks URL. See NestJS AI Gateway for the full architecture.

Auto-Deploy Workflow

Git push to dev/main
--> Amplify webhook detects branch update
--> Provisions build environment
--> Reads SECRET_NAME env var
--> Fetches secrets from Secrets Manager
--> Runs npm install (with dependency cache)
--> Runs npm run build (Next.js SSR build)
--> Deploys SSR output to Amplify hosting
--> SSL certificate verified/renewed
--> Available at dev.aiqlick.com or www.aiqlick.com

Build caching is handled by Amplify's built-in dependency cache for node_modules and .next/cache. Subsequent builds are faster when dependencies have not changed.

Typical build times:

  • Cold build (no cache): 3-5 minutes
  • Warm build (cached deps): 1-3 minutes

Useful CLI Commands

Check App Status

# List Amplify apps
aws amplify list-apps \
--profile Administrator-842697652860 \
--region eu-north-1 \
--output table

# Get app details
aws amplify get-app \
--profile Administrator-842697652860 \
--region eu-north-1 \
--app-id d2x4yh9us5ctu1 \
--output json

List Branches

aws amplify list-branches \
--profile Administrator-842697652860 \
--region eu-north-1 \
--app-id d2x4yh9us5ctu1 \
--output table

Check Recent Builds

# List recent builds for a branch
aws amplify list-jobs \
--profile Administrator-842697652860 \
--region eu-north-1 \
--app-id d2x4yh9us5ctu1 \
--branch-name dev \
--max-results 5 \
--output table

Trigger a Manual Build

# Start a new build for a branch
aws amplify start-job \
--profile Administrator-842697652860 \
--region eu-north-1 \
--app-id d2x4yh9us5ctu1 \
--branch-name dev \
--job-type RELEASE

# Start a rebuild of a specific job
aws amplify start-job \
--profile Administrator-842697652860 \
--region eu-north-1 \
--app-id d2x4yh9us5ctu1 \
--branch-name main \
--job-type RETRY \
--job-id JOB_ID

Check Domain Status

aws amplify get-domain-association \
--profile Administrator-842697652860 \
--region eu-north-1 \
--app-id d2x4yh9us5ctu1 \
--domain-name aiqlick.com \
--output json

View Environment Variables

aws amplify get-branch \
--profile Administrator-842697652860 \
--region eu-north-1 \
--app-id d2x4yh9us5ctu1 \
--branch-name dev \
--query 'branch.environmentVariables' \
--output json

Request Body Size Limits on SSR Routes

Amplify Compute runs Next.js SSR (including app/api/* Route Handlers and server actions) on AWS Lambda. Lambda enforces a request payload cap that is not directly configurable via Amplify:

PathEffective capWhere it comes from
POST /api/upload (and any app/api/* route)~5 MBAmplify Compute → Lambda synchronous invocation body cap
Server actions~1 MB (default)Next.js serverActions.bodySizeLimit
Static assets served from CDNN/AServed from CloudFront, no Lambda involved

When the cap is hit the client receives 413 Payload Too Large from the infrastructure before any application code runs. Your own size guards (if (file.size > 50 * 1024 * 1024) ...) will never fire, and build logs show nothing because no Lambda invocation happened.

caution

This affected the Knowledge Base document uploader (SUP-00072): PDFs over ~5 MB returned 413 even though the Next.js route had a 50 MB self-check. The fix was to stop proxying the file through Amplify entirely — see File Upload Flow.

Working around the cap

The supported patterns for features that may handle files larger than ~5 MB:

  1. Browser → S3 directly via a presigned PUT URL issued by the backend (Knowledge Base, CV extraction use this today).
  2. Multipart S3 uploads from the browser for very large files (>5 GB). Not currently used anywhere in the platform.
  3. Raise the limit — not an option on Amplify Compute.

Anything that POSTs a binary body to app/api/* on the frontend is running through Lambda. If that binary can exceed a few megabytes, the feature will silently start failing for real users once they try larger files.

Troubleshooting

Build Failures

If a build fails, check the build logs in the Amplify console or via CLI:

# Get job details (includes build log URL)
aws amplify get-job \
--profile Administrator-842697652860 \
--region eu-north-1 \
--app-id d2x4yh9us5ctu1 \
--branch-name dev \
--job-id JOB_ID \
--output json

Common build failure causes:

  • Secret fetch failure: The Amplify service role may lack permissions to read from Secrets Manager. Verify the role has secretsmanager:GetSecretValue permission.
  • Dependency install failure: A corrupted node_modules cache can cause issues. Clear the Amplify cache and retry.
  • Build timeout: Large builds may exceed Amplify's default timeout. Check if the build process is stuck on a particular step.
  • TypeScript errors: The production build runs strict type checking. Errors that are warnings locally may fail the build.

Secret Updates Not Taking Effect

Amplify injects secrets at build time, not runtime. After updating a secret in Secrets Manager:

  1. Navigate to the Amplify console or use the CLI to trigger a new build.
  2. Verify the build completes successfully.
  3. The new secret values will only be active after the build deploys.
caution

There is no test suite for the frontend. The pre-commit hook runs scripts/verify-build.sh which executes npm run build and blocks the commit on failure. This is the only automated validation before deployment to Amplify.