fix(app-check)!: skip App Check during server rendering by default - #3773
Open
armando-navarro wants to merge 1 commit into
Open
armando-navarro wants to merge 1 commit into
armando-navarro wants to merge 1 commit into
Conversation
provideAppCheck ran the app's setup function during server rendering, where the reCAPTCHA providers throw "document is not defined", so following docs/app-check.md broke every prerender and server render. The workaround users posted, returning nothing on the server, failed to compile and left an empty AppCheck object behind. The setup function now runs only in the browser, unless the server config provides APP_CHECK_ON_SERVER as true for a server-capable provider. A skipped server injects AppCheck as null, and development mode warns once. Firebase's documented route for App Check in server renders, an appCheckToken passed to initializeServerApp, is unaffected. BREAKING CHANGE: App Check no longer runs during server rendering unless APP_CHECK_ON_SERVER is provided as true. Fixes angular#3488 Fixes angular#3128 Refs angular#3089
tyler-reitz
approved these changes
Sep 25, 2026
tyler-reitz
left a comment
Collaborator
There was a problem hiding this comment.
Approving. Verified locally rather than by reading: built the branch and ran test:chrome-headless (111 passed, 48 skipped), then disabled each behavior in turn against the built bundle. The server skip, the undefined filter, and the APP_CHECK_ON_SERVER opt-in each take their specs red, so the new coverage is real.
Two non-blocking notes:
inject(AppCheck)still types asAppCheck, so SSR code that dereferences it compiles clean and throws at runtime. The dev warning points atdocs/app-check.md, so the docs PR is worth landing in the same release.- When every provided entry is filtered out,
ɵgetDefaultInstanceOffalls through togetImmediate({ optional: true })on the default app. An App Check instance created outside AngularFire would still resolve on the server, so "injects as null" holds for the documented setup but not universally. Inferred fromsrc/core.ts, not run.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #3488
Fixes #3128
Refs #3089
Following
docs/app-check.mdin a server-rendered app fails the build withReferenceError: document is not defined.provideAppCheckruns the app's setup function during server rendering, and the reCAPTCHA providers need a browser. This PR skips App Check during server rendering by default, with an opt-in for apps that run it there on purpose.Important
This is a breaking change, so it needs to merge before
21.0.0is tagged.Breaking change
provideAppCheck, andinject(AppCheck)returnsnullthere. The browser is unchanged.CustomProviderbacked by the Admin SDK, keep the old behavior with one line in their server config:initializeServerAppasappCheckToken. It needs no App Check instance on the server, so this change does not affect it.Changes
appCheckInstanceFactoryreturns early during server rendering unlessAPP_CHECK_ON_SERVERistrue, and in development mode it warns once that it skipped App Check.APP_CHECK_ON_SERVERis a new export from@angular/fire/app-check,falseby default.defaultAppCheckInstanceFactorydrops skipped entries before choosing the default instance.ɵgetDefaultInstanceOfreads.appon every entry, so an app callingprovideAppChecktwice would otherwise crash on the server.src/app-check/app-check.spec.tscover the server default, twoprovideAppCheckcalls on the server, the opt-in, and the browser.Verification
On an Angular 21.2 app rendered at build time, using the setup from
docs/app-check.md:21.0.0-rc.1:ng buildfails withReferenceError: document is not defined.AppCheckisnullon the server.APP_CHECK_ON_SERVERand the reCAPTCHA provider: the original error returns, so the opt-in does run App Check on the server.APP_CHECK_ON_SERVERand aCustomProvideron the server: the build succeeds with a realAppCheckon the server.npm run test:chrome-headless: 111 passed, 48 skipped.npm run test:node: 331 specs, 0 failures.