Skip to content

Route unregistered token spaces to Token tab by default#1660

Merged
j-paterson merged 10 commits intocanaryfrom
codex/route-unregistered-token-spaces-to-/token
Jan 22, 2026
Merged

Route unregistered token spaces to Token tab by default#1660
j-paterson merged 10 commits intocanaryfrom
codex/route-unregistered-token-spaces-to-/token

Conversation

@willyogo
Copy link
Copy Markdown
Member

@willyogo willyogo commented Jan 8, 2026

Motivation

  • Visiting a token space that is not yet registered without a tabName in the URL currently falls back to the profile handling and can cause a stray "Profile" tab to be created.
  • The intended default for unregistered token spaces without a specified tab is the Token tab to avoid creating mismatched tab entries.

Description

  • Removed the global redirect that forced token-space roots to /Profile, letting routing be determined by space data instead of config-level redirects.
  • Added a token-space default-tab lookup from tabOrder so registered spaces resolve their primary tab and unregistered spaces fall back to Token.
  • Redirected bare token-space routes to the computed primary tab, ensuring registered spaces land on their primary tab and unregistered spaces land on Token

This should avoid breaking any token spaces that were registered with "profile" as the primary tab

Testing

  • No automated tests were run on the modified code.

Codex Task

Summary by CodeRabbit

  • New Features

    • Pages now load a stored "default tab" per space and redirect users to that tab when none is specified.
    • Added a utility to retrieve a space's default tab from storage.
  • Bug Fixes

    • Token, channel, proposal, profile, and home pages consistently navigate to the configured default tab when no tab is requested.
  • Behavior

    • Tab management: default-tab guards relaxed—tabs can be renamed or removed when multiple tabs exist.

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link
Copy Markdown

vercel Bot commented Jan 8, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
space-system Ready Ready Preview, Comment Jan 22, 2026 2:11am

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 8, 2026

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Runtime default-tab loading added and hardcoded redirects removed. Page loaders now fetch a space's stored default tab and, when no tab param is provided, redirect to that tab. Several space-data creators became async to await the loaded default; TabBar delete/rename gating was simplified.

Changes

Cohort / File(s) Summary
Routing config
next.config.mjs
Removed the hardcoded redirect mapping /t/:network/:contractAddress/t/:network/:contractAddress/Profile.
Default tab loader
src/common/utils/tabUtils.ts
New exported loadSpaceDefaultTab(spaceId, fallbackTab): Promise<string> reading stored tabOrder and returning first tab or fallback; wraps storage access with try/catch.
Type changes
src/common/types/spaceData.ts
Broadened defaultTab types on ProfileSpacePageData, TokenSpacePageData, ProposalSpacePageData, ChannelSpacePageData from specific literals to string.
Space page redirects (pages)
src/app/(spaces)/t/[network]/[contractAddress]/page.tsx, src/app/(spaces)/c/[channelId]/page.tsx, src/app/(spaces)/p/[proposalId]/page.tsx, src/app/(spaces)/s/[handle]/page.tsx
Added redirect imports and guard logic: after loading space data, if decoded tab param is missing, redirect to URL using the loaded defaultTab.
Space data creators (utils)
src/app/(spaces)/t/[network]/[contractAddress]/utils.ts, src/app/(spaces)/c/[channelId]/utils.ts, src/app/(spaces)/p/[proposalId]/utils.ts, src/app/(spaces)/s/[handle]/utils.ts, src/app/[navSlug]/[[...tabName]]/utils.ts
Replaced hardcoded defaultTab values with calls to loadSpaceDefaultTab(...). Several create*SpaceData helpers were made async and call/return Promises; call sites updated to await. Nav utils removed inline storage retrieval in favor of loadSpaceDefaultTab.
Tab UI logic
src/common/components/organisms/TabBar.tsx
Removed isEditableTab and default-tab-specific guards; rename allowed always, delete allowed when >1 tab (no longer prevents deleting the default tab if multiple tabs exist).
Supabase / config tweak
src/config/nouns/initialSpaces/initialChannelSpace.ts
Replaced direct SDK enum imports with local as const string-literal FeedType / FilterType to avoid runtime/Edge issues (values preserved).
Minor immutability tweak
src/app/api/opengraph/route.ts
letconst for rawImage and rawVideo intermediate variables only.

Sequence Diagram(s)

sequenceDiagram
  participant Browser
  participant NextPage as Next Page Loader
  participant TabUtils as loadSpaceDefaultTab (Server)
  participant Storage as Supabase (Storage)

  Browser->>NextPage: Request /space/:id (no tab param)
  NextPage->>TabUtils: loadSpaceDefaultTab(spaceId, fallback)
  TabUtils->>Storage: fetch tabOrder for spaceId
  Storage-->>TabUtils: tabOrder JSON (or error)
  TabUtils-->>NextPage: resolved defaultTab (first tab or fallback)
  NextPage-->>Browser: redirect to /space/:id/{encoded defaultTab}
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • sktbrd

Poem

"I hopped through code at break of dawn,
I found the tab where defaults yawn,
No longer fixed, they spring and glide,
I push a route — the warren's stride,
🐇✨ Default tabs now lead the tide."

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: routing unregistered token spaces to the Token tab by default, which aligns with the primary objective of fixing fallback behavior for unregistered spaces.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown
Contributor

@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: 0

🧹 Nitpick comments (1)
src/app/(spaces)/t/[network]/[contractAddress]/page.tsx (1)

50-53: Dead code: fallback is unreachable after redirect.

Since redirect() throws when !decodedTabNameParam (lines 38-42), the fallback || tokenSpacePageData.defaultTab on line 52 is never executed. Consider simplifying:

Suggested simplification
      <TokenSpace
        spacePageData={tokenSpacePageData}
-        tabName={decodedTabNameParam || tokenSpacePageData.defaultTab}
+        tabName={decodedTabNameParam}
      />

Alternatively, if you want to keep the fallback for defensive coding (e.g., if the redirect logic changes later), a non-null assertion or comment would clarify intent.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b96e66a and cfd6ef7.

📒 Files selected for processing (4)
  • next.config.mjs
  • src/app/(spaces)/t/[network]/[contractAddress]/page.tsx
  • src/app/(spaces)/t/[network]/[contractAddress]/utils.ts
  • src/common/types/spaceData.ts
💤 Files with no reviewable changes (1)
  • next.config.mjs
🧰 Additional context used
🧬 Code graph analysis (1)
src/app/(spaces)/t/[network]/[contractAddress]/utils.ts (1)
src/common/data/database/supabase/clients/server.ts (1)
  • createSupabaseServerClient (7-7)
🔇 Additional comments (5)
src/common/types/spaceData.ts (1)

46-54: LGTM - Type change supports dynamic default tab resolution.

The broadening from literal 'Token' to string enables the runtime-determined default tab. This is consistent with the base SpacePageData.defaultTab type on line 25.

src/app/(spaces)/t/[network]/[contractAddress]/page.tsx (1)

37-42: LGTM - Redirect to computed default tab.

The redirect correctly routes bare token-space URLs to the resolved default tab. Since redirect() throws internally in Next.js, execution won't continue past this point when !decodedTabNameParam.

src/app/(spaces)/t/[network]/[contractAddress]/utils.ts (3)

94-117: LGTM - Well-structured helper with appropriate error handling.

The function correctly:

  • Returns early when no spaceId is provided
  • Uses try-catch to handle JSON parsing and storage errors gracefully
  • Falls back to undefined on any failure, allowing the caller to use a default

One consideration: the returned tab name is not validated against a known set of tabs. If storage contains an invalid tab name, it will be used as-is. This may be intentional to support custom tabs.


242-243: LGTM - Correct fallback chain for default tab resolution.

The logic correctly resolves the default tab from the space's tabOrder configuration, falling back to "Token" for unregistered spaces. This aligns with the PR objective.


274-287: Verify the returned defaultTab is propagated correctly.

The defaultTab property is now dynamic. Confirm downstream consumers (particularly the page component's redirect logic) handle all possible values correctly.

#!/bin/bash
# Verify how defaultTab is used across the codebase
rg -n --type=ts -C3 'defaultTab' src/app/

@j-paterson j-paterson marked this pull request as draft January 15, 2026 19:55
@j-paterson j-paterson force-pushed the codex/route-unregistered-token-spaces-to-/token branch from cfd6ef7 to 4bc0bff Compare January 22, 2026 01:44
- Add shared loadSpaceDefaultTab utility function for consistent tab loading
- Update all space types (Profile, Channel, Proposal, Token, NavPage) to use dynamic default tabs from tabOrder storage
- Change defaultTab type from literal strings to string for all space types
- Add redirect logic to Profile, Channel, and Proposal pages when no tab specified
- Update TabBar to only show delete button when more than one tab exists
- Allow renaming/deleting default tab as long as at least one tab remains
- Ensure at least one tab always remains (enforced in UI and deletion logic)
Revert changes to:
- src/config/index.ts (remove Clanker-specific config system)
- src/config/clanker/initialSpaces/initialHomebase.ts (remove new file)
- package.json (revert dependency updates)
- yarn.lock (revert lock file changes)
Replace @neynar/nodejs-sdk imports with local string constants to avoid
pulling in axios (which uses Node.js APIs) when config is imported in
Edge Runtime contexts (e.g., /api/metadata/community).

The enum values match the SDK:
- FeedType.Filter = 'filter'
- FilterType.ChannelId = 'channel_id'
@j-paterson j-paterson marked this pull request as ready for review January 22, 2026 02:23
@j-paterson j-paterson merged commit 81eb3a9 into canary Jan 22, 2026
4 of 5 checks passed
@j-paterson j-paterson deleted the codex/route-unregistered-token-spaces-to-/token branch January 22, 2026 02:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

codex LGFTP Looks Good From Testing Perspective

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants