Skip to content

feat: Full URL deep linking — copy/paste URLs to recreate any view#24

Merged
homeles merged 3 commits into
mainfrom
feat/url-deep-linking
Apr 15, 2026
Merged

feat: Full URL deep linking — copy/paste URLs to recreate any view#24
homeles merged 3 commits into
mainfrom
feat/url-deep-linking

Conversation

@lupita-hom
Copy link
Copy Markdown
Collaborator

Summary

All view state is now synced to URL search params. Copy/paste a URL into a new tab to recreate the exact same view with the same repo, date range, filters, and sorting.

URL Schema

View Params Example
Global range, since, until ?range=3m or ?range=custom&since=2026-01-14&until=2026-04-15
Commit Graph branches &branches=main,dev
Network Graph branches &branches=main,dev
Pull Requests state, sort, author, reviewer &state=OPEN&sort=newest&author=homeles
Code Frequency tab, path &tab=treemap&path=src/
Branches sort, tab, q &tab=tags&q=v1

Implementation

  • useUrlParams.ts (new) — useUpdateSearchParams() merges params without clobbering; useDateRangeParams() bidirectional context↔URL sync with ref-based echo prevention
  • All pages — lazy useState from URL params, useEffect writes back on change
  • AppLayout — preserves date range params when switching repos, sidebar links preserve query string
  • Defaults omitted from URL to keep it clean (range=1w, state=OPEN, sort=newest etc. are not written)

Files

  • Created: client/src/hooks/useUrlParams.ts
  • Modified: AppLayout, GraphPage, NetworkPage, PullRequestsPage, CodeFrequencyPage, BranchesPage

TypeScript tsc -b clean on both client and server.

Copy/paste any URL to recreate the exact same view with same repo,
date range, filters, sorting, and selections.

URL schema:
- Global: ?range=1w (or range=custom&since=2026-01-14&until=2026-04-15)
- Commit Graph: &branches=main,dev
- Network Graph: &branches=main,dev
- Pull Requests: &state=OPEN&sort=newest&author=homeles&reviewer=octocat
- Code Frequency: &tab=timeseries&path=src/
- Branches: &sort=updated&tab=branches&q=fix

Implementation:
- New useUpdateSearchParams() hook for merging params without clobbering
- New useDateRangeParams() for bidirectional context↔URL sync with echo prevention
- All pages init state from URL params (lazy useState)
- Defaults omitted from URL to keep it clean
- AppLayout preserves date range params when switching repos/views
- Sidebar nav links preserve query string
When loading a URL like /app/repo/ActionsDesk/ghec-enterprise-reporting,
the org dropdown showed 'Personal' and repo showed 'Select repository...'
because selectedOwner initialized to null (Personal repos only).

Fix: initialize selectedOwner from URL params.owner, and sync it when
the URL owner changes. This ensures useOrgRepos fetches repos for the
correct org, so currentRepo is found and the dropdown shows the right name.
Custom date ranges from URL (?range=custom&since=2026-03-07&until=2026-04-14)
were being ignored because the context initialized with default '1w' values.
The useDateRangeParams() hook updated it in a useEffect (after first render),
but by then the first data fetch had already fired with wrong dates.

Fix: DateRangeProvider now reads URL params synchronously during initial
useState via getInitialRange(). This means the very first render has the
correct date range, and the first data fetch uses the right params.
@homeles homeles merged commit f4ede61 into main Apr 15, 2026
1 check passed
@homeles homeles deleted the feat/url-deep-linking branch April 16, 2026 18:53
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