Skip to content

fix(webapp): remove env from non-env-specific page URLs#6098

Merged
macko911 merged 11 commits into
masterfrom
matej/nan-5447-non-environment-specific-pages-still-have-the-env-in-the-url
May 21, 2026
Merged

fix(webapp): remove env from non-env-specific page URLs#6098
macko911 merged 11 commits into
masterfrom
matej/nan-5447-non-environment-specific-pages-still-have-the-env-in-the-url

Conversation

@macko911

@macko911 macko911 commented May 11, 2026

Copy link
Copy Markdown
Contributor

Problem

Team settings, user settings, and team billing pages were nested under /:env/ giving them URLs like /dev/team-settings. These pages are team/user-level and not environment-specific, making them hard to link from documentation.

Solution

Moves them to env-free paths: /team-settings, /user-settings, /team/billing. Old env-prefixed URLs redirect to the new paths for backward compat.

These pages still read env from the Zustand store (not from the URL) to make env-scoped API calls (e.g. useTeam(env)). The store is seeded from localStorage on load and kept in sync by PrivateRoute whenever the user is on an env-specific page. For direct navigation to these pages, PrivateRoute now validates the stored env against meta.environments and falls back to a valid one if stale — so API calls always get a real env regardless of what's in the URL.

Note: the new top-level routes (/team-settings, /user-settings, /team) are now reserved and would shadow any environment with the same name. Validated against the prod DB — no existing account uses any of these as an env name. Follow-up: NAN-5521 to block these names at env creation time.

Fixes NAN-5447

Testing

  • Navigate to /team-settings, /user-settings, /team/billing — pages load without env in URL
  • Navigate to /dev/team-settings — redirects to /team-settings
  • Switch environment while on /team-settings — URL stays at /team-settings
  • Env-specific pages (/dev/integrations, /dev/connections) still work normally

@linear

linear Bot commented May 11, 2026

Copy link
Copy Markdown

NAN-5447

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

1 issue found across 12 files

Confidence score: 3/5

  • There is a concrete regression risk in packages/webapp/src/components/PrivateRoute.tsx: stale notFoundEnv/unauthorizedEnv flags can persist and incorrectly block navigation to env-free pages.
  • Because this is a user-facing routing/access behavior issue (severity 6/10, confidence 8/10), the merge risk is moderate rather than minimal.
  • This looks straightforward to mitigate by resetting the env error flags before early returns on non-env paths, which should reduce the chance of false blocking.
  • Pay close attention to packages/webapp/src/components/PrivateRoute.tsx - env error state needs to be cleared on non-env route handling to avoid stale access denials.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/webapp/src/components/PrivateRoute.tsx">

<violation number="1" location="packages/webapp/src/components/PrivateRoute.tsx:52">
P2: Reset env error flags before returning for non-env paths; otherwise stale `notFoundEnv`/`unauthorizedEnv` state can incorrectly block the new env-free pages.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.

Comment thread packages/webapp/src/components/PrivateRoute.tsx Outdated
@macko911 macko911 force-pushed the matej/nan-5447-non-environment-specific-pages-still-have-the-env-in-the-url branch from a4af425 to 6fe2d9b Compare May 11, 2026 11:20
@macko911 macko911 marked this pull request as ready for review May 11, 2026 13:21
@superagent-security superagent-security Bot added contributor:verified Contributor passed trust analysis. pr:verified PR passed security analysis. labels May 11, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6fe2d9b564

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/webapp/src/components/PrivateRoute.tsx Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 58f239c667

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/webapp/src/components/PrivateRoute.tsx Outdated
Comment thread packages/webapp/src/App.tsx Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

1 issue found across 1 file (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/webapp/src/components/PrivateRoute.tsx">

<violation number="1" location="packages/webapp/src/components/PrivateRoute.tsx:75">
P2: `notFoundEnv` can remain stuck `true` after navigation because it is no longer reset on valid/non-env paths.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.
Fix all with cubic

Comment thread packages/webapp/src/components/PrivateRoute.tsx Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c5a7e3fea2

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/webapp/src/components/PrivateRoute.tsx Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9d560a73f1

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/webapp/src/components/PrivateRoute.tsx Outdated
Comment thread packages/webapp/src/App.tsx

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3edfaf232f

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/webapp/src/utils/routes.ts Outdated
@macko911 macko911 force-pushed the matej/nan-5447-non-environment-specific-pages-still-have-the-env-in-the-url branch from 3edfaf2 to d90a1d7 Compare May 18, 2026 06:50

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d90a1d78e7

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread package-lock.json Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: df19a65847

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/webapp/src/utils/routes.ts Outdated

@kaposke kaposke left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We already had a fix in place to make it linkable in docs. /team-settings, /user-settings, /team/billing should all work as links in the docs. It will find an environment and redirect you to it (eg: /dev/team/billing).

This PR achieves it with clean paths without the environment, relying on what is on localstorage to load an environment. It seems to work well, so I'm fine with shipping. I found a bug: if you rename the environment you're currently in from another tab, navigating back to one of the environment dependent route will break and sign you off. Very edge case though.

I believe Bastien forgot there was a fix in place. Worth double-checking if this is needed, and the tradeoff.

@macko911

Copy link
Copy Markdown
Contributor Author

@kaposke Thanks for the review 🙏

On the existing fix — you're right that RedirectWithEnv already made these pages linkable, but it still landed users on /:env/team-settings in the end. I'll check with Bastien if he still wants to go ahead with this change.

Good catch on the rename-env bug. I believe this is pre-existing, not a regression from this PR. I've created NAN-5663 as a follow-up fix.

Matej Vobornik and others added 10 commits May 20, 2026 15:05
Team settings, user settings, and team billing pages were nested under
/:env/ giving them URLs like /dev/team-settings. These pages are
team/user-level and not environment-scoped, making them hard to link
from documentation.

Move them to /team-settings, /user-settings, and /team/billing with
backward-compat redirects from the old env-prefixed paths.
Move the non-env path list to a shared utils/routes.ts so
PrivateRoute and EnvironmentDropdown stay in sync. Also switch
EnvironmentDropdown to a startsWith check (same as PrivateRoute)
for precise path matching, and revert an unrelated package-lock.json
pubsub dependency move.
Instead of an early return with duplicated env-resolution logic for
non-env paths, thread an isNonEnvPath flag through the existing
validation block. This removes the duplicate fallback and ensures
non-env pages benefit from the same prod-env access guard logic.
Remove the !isNonEnvPath guard from the production-access check so
that a stale prod env in the store is replaced even when navigating
to /team-settings, /user-settings, or /team/billing. The
PageEnvironmentUnauthorized splash is still suppressed for non-env
paths via setUnauthorizedEnv(!isNonEnvPath). Also reset notFoundEnv
to false in the valid-env branch to prevent it staying stuck true
after navigating away from an invalid-env path.
Use a RedirectPreservingLocation component instead of plain Navigate
so that backward-compat redirects (e.g. /dev/team/billing?tab=usage)
forward search params and hash fragments to the new URLs.
startsWith('/team-settings') would incorrectly match a hypothetical
/team-settings-prod env path. Replace the raw startsWith check with
an isNonEnvPath helper that requires either an exact match or a
trailing slash, ensuring /team-settings-* env paths remain
env-specific.
/:env/team-settings etc. were still evaluated as env-scoped, so a
stale or unauthorized env segment could show PageNotFound before the
redirect route ran. Strip the leading env segment and check the
remainder against NON_ENV_PATH_PREFIXES to handle both old and new
URL forms.
@macko911 macko911 force-pushed the matej/nan-5447-non-environment-specific-pages-still-have-the-env-in-the-url branch from cc29063 to fadcc24 Compare May 20, 2026 13:05

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fadcc24419

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/webapp/src/components/PrivateRoute.tsx
@macko911 macko911 added this pull request to the merge queue May 21, 2026
Merged via the queue into master with commit c9797db May 21, 2026
27 checks passed
@macko911 macko911 deleted the matej/nan-5447-non-environment-specific-pages-still-have-the-env-in-the-url branch May 21, 2026 07:56
sapnesh-nango pushed a commit that referenced this pull request May 24, 2026
## Problem
Team settings, user settings, and team billing pages were nested under
`/:env/` giving them URLs like `/dev/team-settings`. These pages are
team/user-level and not environment-specific, making them hard to link
from documentation.

## Solution
Moves them to env-free paths: `/team-settings`, `/user-settings`,
`/team/billing`. Old env-prefixed URLs redirect to the new paths for
backward compat.

These pages still read `env` from the Zustand store (not from the URL)
to make env-scoped API calls (e.g. `useTeam(env)`). The store is seeded
from `localStorage` on load and kept in sync by `PrivateRoute` whenever
the user is on an env-specific page. For direct navigation to these
pages, `PrivateRoute` now validates the stored env against
`meta.environments` and falls back to a valid one if stale — so API
calls always get a real env regardless of what's in the URL.

Note: the new top-level routes (`/team-settings`, `/user-settings`,
`/team`) are now reserved and would shadow any environment with the same
name. Validated against the prod DB — no existing account uses any of
these as an env name. Follow-up:
[NAN-5521](https://linear.app/nango/issue/NAN-5521) to block these names
at env creation time.

Fixes [NAN-5447](https://linear.app/nangohq/issue/NAN-5447)

## Testing
- Navigate to `/team-settings`, `/user-settings`, `/team/billing` —
pages load without env in URL
- Navigate to `/dev/team-settings` — redirects to `/team-settings`
- Switch environment while on `/team-settings` — URL stays at
`/team-settings`
- Env-specific pages (`/dev/integrations`, `/dev/connections`) still
work normally

---------

Co-authored-by: Matej Vobornik <matej.vobornik@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contributor:verified Contributor passed trust analysis. pr:verified PR passed security analysis.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants