Skip to content

feat: autogenerate default allowedHosts and trustProxyHeaders#427

Open
hrishikesh-k wants to merge 27 commits into
mainfrom
hk/angular-22
Open

feat: autogenerate default allowedHosts and trustProxyHeaders#427
hrishikesh-k wants to merge 27 commits into
mainfrom
hk/angular-22

Conversation

@hrishikesh-k
Copy link
Copy Markdown
Contributor

Angular introduced allowedHosts and trustProxyHeaders config to control wheter or not to SSR a request. On Netlify, there could be a variety of URLs for each site/deploy. Thus, we now auto-generate a default config for the users.

@hrishikesh-k hrishikesh-k requested a review from a team as a code owner May 14, 2026 12:36
@netlify
Copy link
Copy Markdown

netlify Bot commented May 14, 2026

Deploy Preview for angular-runtime-demo ready!

Name Link
🔨 Latest commit 35aa5cb
🔍 Latest deploy log https://app.netlify.com/projects/angular-runtime-demo/deploys/6a0758464262be00082eb475
😎 Deploy Preview https://deploy-preview-427--angular-runtime-demo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 14, 2026

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds an App Engine configuration module that exports getAllowedHosts() and getTrustProxyHeaders(), exposes them via package subpath exports and types, injects runtime env into Edge Function polyfills, wires the configuration into the demo AngularAppEngine handler, updates demo Angular dependency versions to ^21.2.11, adjusts some build error messages, tightens Context typing, and refreshes README examples to use Angular’s REQUEST/REQUEST_CONTEXT tokens, typed Context imports, and netlify-cli v26.0.0 requirement.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • netlify/angular-runtime#424: Overlaps on context and .js entrypoint changes; related updates to context typing and demo server usage.

Suggested labels

type: feature

Suggested reviewers

  • pieh
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: auto-generating default allowedHosts and trustProxyHeaders configuration values.
Description check ✅ Passed The description is directly related to the changeset, explaining the purpose of auto-generating allowedHosts and trustProxyHeaders configuration.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch hk/angular-22

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
src/app-engine-config.js (2)

11-19: ⚡ Quick win

Consider adding error handling for URL parsing.

If any of the Netlify environment variables contain malformed URLs, the new URL() calls will throw and potentially crash the build. While Netlify should always provide valid URLs, defensive error handling would make the code more robust.

🛡️ Proposed error handling
 export function getAllowedHosts() {
   const allowedHosts = []
 
   if (!env.DEPLOY_ID || !env.DEPLOY_PRIME_URL || !env.DEPLOY_URL || !env.SITE_ID || !env.SITE_NAME || !env.URL) {
     console.warn('Missing Netlify-specific environment variable(s). `allowedHosts` config might be incomplete.')
     return allowedHosts
   }
 
+  try {
     const deployPrimeUrlHostname = new URL(env.DEPLOY_PRIME_URL).hostname
 
     // <subdomain>.netlify.app OR <custom-domain>
     // www handling is not required as Netlify will auto-redirect
     allowedHosts.push(new URL(env.URL).hostname)
     // <deploy-id>--<subdomain>.netlify.app
     allowedHosts.push(new URL(env.DEPLOY_URL).hostname)
     // <branch-name>--<subdomain>.netlify.app or <dp-#>--<subdomain>.netlify.app (supports ADS)
     allowedHosts.push(deployPrimeUrlHostname)
+  } catch (error) {
+    console.warn('Failed to parse Netlify URL environment variables:', error.message)
+    return allowedHosts
+  }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app-engine-config.js` around lines 11 - 19, Wrap each new URL(...) call
that pushes into allowedHosts (the uses of env.URL, env.DEPLOY_URL, and
env.DEPLOY_PRIME_URL / deployPrimeUrlHostname) in defensive parsing: check the
env var exists, attempt parsing inside a try/catch, and only push hostname to
allowedHosts if parsing succeeds; on failure log or warn (e.g., via console.warn
or processLogger) and skip that entry so a malformed Netlify URL cannot throw
and crash the build. Ensure the code still computes deployPrimeUrlHostname from
env.DEPLOY_PRIME_URL using the same guarded logic.

33-37: 💤 Low value

The split logic assumes a single -- separator in the URL; if a branch name contained --, the extraction would be incomplete.

The code at line 34 splits on -- and takes the first element, which works for typical Netlify deploy preview URLs like feature--site.netlify.app. However, if a branch name itself contained -- (e.g., feature--fix), it would extract only feature instead of feature--fix. This is a theoretical edge case, as Netlify likely sanitizes branch names for URL safety, but a more robust approach would split from the right to isolate the site name/ID portion.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app-engine-config.js` around lines 33 - 37, The current logic splits
deployPrimeUrlHostname on '--' and takes the first element which fails if the
branch name itself contains '--'; instead locate the last '--' (e.g., using
lastIndexOf) and take the substring before that to produce branchNameOrDpNumber,
then push the two allowedHosts using that value with env.SITE_NAME and
env.SITE_ID; update the block that reads deployPrimeUrlHostname and the
references to allowedHosts so the branch extraction uses the rightmost separator
rather than split().
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@README.md`:
- Line 131: Update the README examples that reference context.url.pathname to
use the same URL parsing used in the runtime templates: replace usages of
context.url.pathname with new URL(request.url).pathname in the example API
endpoint checks (matching the logic in serverModuleHelpers.js); ensure all
occurrences (the examples around the earlier lines like the ones referenced)
consistently parse the request URL via new URL(request.url).pathname so the docs
match generated code.

In `@src/app-engine-config.js`:
- Around line 6-9: The current env-check block returns the empty allowedHosts
array when Netlify vars are missing, which causes AngularAppEngine to reject all
hostnames; change the fallback so that instead of returning allowedHosts (empty
array) you return undefined (or null) to let the engine use its default
permissive behavior, or alternatively populate allowedHosts with a safe default
(e.g., localhost and 127.0.0.1) — locate the env check that references
env.DEPLOY_ID / DEPLOY_PRIME_URL / DEPLOY_URL / SITE_ID / SITE_NAME / URL and
modify the early-return to return undefined (or set allowedHosts to a minimal
safe list) rather than the empty allowedHosts.

---

Nitpick comments:
In `@src/app-engine-config.js`:
- Around line 11-19: Wrap each new URL(...) call that pushes into allowedHosts
(the uses of env.URL, env.DEPLOY_URL, and env.DEPLOY_PRIME_URL /
deployPrimeUrlHostname) in defensive parsing: check the env var exists, attempt
parsing inside a try/catch, and only push hostname to allowedHosts if parsing
succeeds; on failure log or warn (e.g., via console.warn or processLogger) and
skip that entry so a malformed Netlify URL cannot throw and crash the build.
Ensure the code still computes deployPrimeUrlHostname from env.DEPLOY_PRIME_URL
using the same guarded logic.
- Around line 33-37: The current logic splits deployPrimeUrlHostname on '--' and
takes the first element which fails if the branch name itself contains '--';
instead locate the last '--' (e.g., using lastIndexOf) and take the substring
before that to produce branchNameOrDpNumber, then push the two allowedHosts
using that value with env.SITE_NAME and env.SITE_ID; update the block that reads
deployPrimeUrlHostname and the references to allowedHosts so the branch
extraction uses the rightmost separator rather than split().
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a463a6f3-ee04-4e99-8a9a-94a46de86358

📥 Commits

Reviewing files that changed from the base of the PR and between 5e8936e and 43517b0.

⛔ Files ignored due to path filters (2)
  • demo/package-lock.json is excluded by !**/package-lock.json
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (8)
  • README.md
  • demo/package.json
  • demo/server.ts
  • package.json
  • src/app-engine-config.d.ts
  • src/app-engine-config.js
  • src/helpers/serverModuleHelpers.js
  • src/helpers/setUpEdgeFunction.js

Comment thread README.md Outdated
Comment thread src/app-engine-config.js Outdated
Comment thread README.md
Comment thread README.md Outdated
@pieh
Copy link
Copy Markdown
Contributor

pieh commented May 15, 2026

As part of this PR we should also adjust

// eslint-disable-next-line no-inline-comments
const NetlifyServerTsAppEngine = /* typescript */ `import { AngularAppEngine, createRequestHandler } from '@angular/ssr'
import { getContext } from '@netlify/angular-runtime/context.js'
const angularAppEngine = new AngularAppEngine()
export async function netlifyAppEngineHandler(request: Request): Promise<Response> {
const context = getContext()
// Example API endpoints can be defined here.
// Uncomment and define endpoints as necessary.
// const pathname = new URL(request.url).pathname;
// if (pathname === '/api/hello') {
// return Response.json({ message: 'Hello from the API' });
// }
const result = await angularAppEngine.handle(request, context)
return result || new Response('Not found', { status: 404 })
}
/**
* The request handler used by the Angular CLI (dev-server and during build).
*/
export const reqHandler = createRequestHandler(netlifyAppEngineHandler)
`
to make use of the new helper.

That "template" is used in 2 ways:

  1. Angular-runtime checks project's server.ts file (this is part of the angular, user project) and if it's one of "known ones" (which we track in https://github.com/netlify/angular-runtime/tree/main/tools/known-server-ts-signatures/AppEngine) we automatically swap it for Netlify-compatible one from the template. This is done, so if user have default entrypoint - they don't need to change additional things to make it work on Netlify.
  2. If check from point 1. sees server.ts it doesn't know about - it will fail the build print the message that user should update their server.ts to be Netlify-compatible in
    // Angular 20+ made App Engine stable, so we should not recommend Common Engine anymore
    failBuild(
    `server.ts doesn't seem to be Netlify compatible and is not known default. Please replace it with Netlify compatible server.ts:\n\n\`\`\`\n${NetlifyServerTsAppEngine}\`\`\`${moreDetailsInRepoReadme}`,
    )
    We do this, because server.ts is something that users can customize and if user has customized it - we don't want to silently replace it with ours because all those customizations would have no effect and this might be confusing - so instead we let user know that they manually need to use Netlify compatible entry and then they can customize it.

Additionally it probably would be good to check if scaffolding new angular project (npx @angular/cli new) generates a server.ts shape that we currently don't track (this would make it not "known to angular-runtime") and if so - add it to tools/known-server-ts-signatures "fixtures" and rerun tools/generate-known-server-ts-signature.mjs, so that we could get into point 1. without having users to manually swap server.ts if they don't do any customizations

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/app-engine-config.js`:
- Around line 7-13: The loop is using for...in so environmentVariable is an
index ("0","1",...) causing env[environmentVariable] to check wrong keys and the
function to return early; change the loop to for (const environmentVariable of
environmentVariables) so the item is the actual env var name, and remove the
early return inside the loop (only return allowedHosts after the loop completes)
to allow all allowedHosts to be populated; update checks that reference
environmentVariables, env, and allowedHosts accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c080124a-7af3-4df4-b8bb-8791b265b53d

📥 Commits

Reviewing files that changed from the base of the PR and between 766344a and ed297f1.

⛔ Files ignored due to path filters (1)
  • demo/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (2)
  • src/app-engine-config.js
  • src/helpers/setUpEdgeFunction.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/helpers/setUpEdgeFunction.js

Comment thread src/app-engine-config.js Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/app-engine-config.js`:
- Around line 39-42: The code currently sets branchNameOrDpNumber by taking the
first token of deployPrimeUrlHostname.split('--'), which yields only the leading
fragment (e.g., "feature") instead of the full branch/DP token up to the last
delimiter (e.g., "feature--api"); change the extraction to use everything before
the last '--' delimiter (use lastIndexOf('--') on deployPrimeUrlHostname and
substring(0, idx) or split and join parts.slice(0, -1).join('--')) and then push
those correctly formed values into allowedHosts (the lines that push
`${branchNameOrDpNumber}--${env.SITE_NAME}.netlify.app` and
`${branchNameOrDpNumber}--${env.SITE_ID}.netlify.app`).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 05dc198c-4bbf-4448-b6f0-098b25c2bd6a

📥 Commits

Reviewing files that changed from the base of the PR and between ed297f1 and 306b642.

📒 Files selected for processing (1)
  • src/app-engine-config.js

Comment thread src/app-engine.js
@hrishikesh-k
Copy link
Copy Markdown
Contributor Author

@pieh thanks for the note about updating the template. I had gone through the codebase and had landed on that part, so updating that was on the to-do list. As we move on with the migration, I'll make sure to check the default server.ts generated by Angular 22 and update it - thanks for that nice piece of info!

Comment thread src/helpers/serverModuleHelpers.js Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants