Firebase Auth on Replit: domains, Secrets and custom domains

Updated 26 Oct 2026 · Pewterkit Guides

Firebase rejects sign-in from any host that isn't on your project's Authorized domains list, and a Replit app runs on at least two hosts: a temporary *.replit.dev development URL that can change, and your published *.replit.app (or custom) domain. Add the exact hosts you use, keep authDomain on firebaseapp.com unless you can proxy /__/auth/*, and re-check the dev host whenever Sign in with Google starts failing again.

Why it breaks on Replit

  • The development URL is temporary. Replit's docs describe it as UUID.servername.replit.dev, live only while you work in the app, and say it "can change each time you reopen the app." An authorized domain you added yesterday may not match today's URL, so you get auth/unauthorized-domain ("This domain is not authorized for OAuth operations for your Firebase project").
  • The published app is a different host. Publishing gives you <name>.replit.app, and each custom domain or subdomain (including www) is another host.
  • Old repl.co addresses have moved. Replit moved repl.co hosting to replit.dev on January 1, 2024. If your authorized domains or OAuth settings still list a repl.co host, it does nothing for current apps.

Step 1: Find the exact hosts your app uses

Replit sets environment variables you can print from the Shell tool:

echo "$REPLIT_DEV_DOMAIN"   # current development host
echo "$REPLIT_DOMAINS"      # domains Replit reports for this app

You can also open Preview and read the ...replit.dev host from its location bar, or use "Open in new tab" and copy it from the address bar. For the published app, the host is shown in the Publishing tool (<name>.replit.app, plus any custom domains).

Step 2: Add them to Firebase's authorized domains

  1. In the Firebase console, open Security > Authentication > Settings (older guides say Build > Authentication > Settings; the Firebase docs use Security as of Oct 2026).
  2. Under Authorized domains, click Add domain and add, host name only (no https://, no path): - the current development host, e.g. 1a2b3c4d-....servername.replit.dev - yourapp.replit.app - each custom domain you serve, e.g. example.com and www.example.com
  3. When the dev host changes, add the new one and remove the stale one.

Don't add the bare platform domain replit.dev or replit.app as a shortcut. The Firebase JS SDK's origin check treats an authorized domain as also covering its subdomains, so a shared platform domain would also accept other people's Replit apps. Why wildcards aren't the answer: authorized domains wildcard.

Step 3: Put the Firebase config somewhere sensible

Firebase's web config is not a secret: Firebase says API keys for Firebase services "are OK to include in code or checked-in config files." Restrict the key in Google Cloud and protect data with Security Rules. Real secrets (a service account JSON for the Admin SDK, for example) belong in Replit Secrets.

If you still want the config out of the code:

  1. Open Tools > Secrets (under Setup) and add keys, e.g. VITE_FIREBASE_API_KEY, VITE_FIREBASE_AUTH_DOMAIN, VITE_FIREBASE_PROJECT_ID, VITE_FIREBASE_APP_ID. Secrets reach your app as environment variables.
  2. If your frontend is built with Vite, only variables prefixed VITE_ are exposed to browser code, and their values are baked into the bundle at build time:

```js // src/firebase.js import { initializeApp } from 'firebase/app'; import { getAuth, GoogleAuthProvider, signInWithPopup } from 'firebase/auth';

const app = initializeApp({ apiKey: import.meta.env.VITE_FIREBASE_API_KEY, authDomain: import.meta.env.VITE_FIREBASE_AUTH_DOMAIN, // YOUR-PROJECT.firebaseapp.com projectId: import.meta.env.VITE_FIREBASE_PROJECT_ID, appId: import.meta.env.VITE_FIREBASE_APP_ID, });

export const auth = getAuth(app); export const signInWithGoogle = () => signInWithPopup(auth, new GoogleAuthProvider()); ```

  1. Check the published app's values too: in Publishing > Adjust settings > Production app secrets. Replit notes Secrets are available for all deployment types except Static Deployments, so a Static Deployment needs the values in code or in a build step that has them.

Step 4: Decide what a custom domain means for authDomain

Adding a custom domain to a Replit deployment does not change authDomain. Leave it as YOUR-PROJECT.firebaseapp.com and signInWithPopup() keeps working on every authorized host; Google's screen will show the firebaseapp.com name.

To make sign-in run on your own domain (needed for signInWithRedirect() on browsers that block third-party storage, and to show your domain on the Google screen), https://your-domain/__/auth/* must be forwarded to https://YOUR-PROJECT.firebaseapp.com/__/auth/*. What you can do depends on the deployment type:

  • Autoscale or Reserved VM (your server runs): add a transparent proxy in your Express server, before your other routes.

```js import { createProxyMiddleware } from 'http-proxy-middleware';

app.use( createProxyMiddleware({ target: 'https://YOUR-PROJECT.firebaseapp.com', changeOrigin: true, pathFilter: '//auth', // keeps the full //auth/... path }), ); ```

Firebase's docs say the proxy must forward GET and POST requests transparently. Register it before any body parser such as express.json(). Test this on a preview deployment before relying on it.

  • Static Deployment: there is no server, and Replit's rewrites "can only redirect to files within your Static Deployment," so they can't proxy to Firebase. Firebase's alternative is to self-host the helper files (/__/auth/handler, handler.js, experiments.js, iframe, iframe.js, links, links.js, /__/firebase/init.json) and re-sync them periodically; it doesn't support Apple sign-in or SAML. Otherwise keep the default authDomain.
  • Cloudflare in front of Replit is not a documented route: Replit's custom-domain docs warn that proxied (orange-cloud) Cloudflare records cause setup issues, because Replit can't renew certificates for them, and say to set records to DNS only.

Once /__/auth is served from your domain:

  1. Set authDomain to that domain, e.g. app.example.com.
  2. In Google Cloud, open the Clients page (console.cloud.google.com/auth/clients, as of Oct 2026), edit the Web client Firebase created, and add https://app.example.com/__/auth/handler under Authorized redirect URIs.
  3. Keep app.example.com in Firebase's authorized domains.

Do this only on a stable host such as your custom domain or yourapp.replit.app; the changing replit.dev host can't hold a stable redirect URI. The full switch is covered in change Firebase authDomain.

How to confirm it worked

  1. Open the dev URL in a new tab, click Sign in with Google, pick an account. The popup should close and auth.currentUser should be set (log it, or watch onAuthStateChanged).
  2. Repeat on yourapp.replit.app and each custom domain. A host that still fails is a host missing from the list.
  3. If you added the proxy, https://your-domain/__/auth/handler should return a Firebase page, not your app's 404 or index page.

FAQ

Why does Firebase sign-in break every time I reopen my Repl?

Replit's development URL can change each time you reopen the app, and Firebase only accepts hosts on your authorized domains list. Print $REPLIT_DEV_DOMAIN, add the new host and remove the old one.

Can I just add replit.dev to Firebase authorized domains?

It would cover the changing dev host, but the Firebase JS SDK's origin check also accepts subdomains of an authorized domain, so it would open your project to every app on that shared domain. Add exact hosts instead, and use your published domain for anything real.

Should my Firebase config go in Replit Secrets?

It can, but it doesn't have to: Firebase API keys for Firebase services are OK in client code. Use Secrets for real secrets such as Admin SDK credentials, and remember a Vite frontend only exposes VITE_-prefixed variables.

Does connecting a custom domain on Replit change my authDomain?

No. authDomain stays YOUR-PROJECT.firebaseapp.com until you change it yourself, and you should only change it once your domain serves /__/auth/* through a proxy or self-hosted helper files.

Do repl.co URLs still work for Firebase Auth?

Replit moved repl.co hosting to replit.dev on January 1, 2024. Authorize your current replit.dev, replit.app or custom hosts instead.

Sources

  1. Replit Docs: Development URLs
  2. Replit Docs: Preview
  3. Replit Docs: Secrets
  4. Replit Docs: Custom domains
  5. Replit Docs: Deployment types
  6. Replit Docs: Static Deployments advanced configuration
  7. Replit Blog: Changes to Hosting on Replit
  8. Firebase: Authenticate with Firebase Using Email Link in JavaScript (authorized domains path)
  9. Firebase: Best practices for using signInWithRedirect on browsers that block third-party storage access
  10. Firebase: Learn about using and managing API keys
  11. Firebase JS SDK source: auth error messages
  12. Firebase JS SDK source: origin validation
  13. Vite: Env Variables and Modes
  14. http-proxy-middleware README
  15. Google Identity: Using OAuth 2.0 for Web Server Applications

How this page was made: drafted with AI from the sources listed, reviewed by Pewterkit. Docs checked 26 Oct 2026. Spotted something out of date? Tell us.

Related guides