Skip to content

Commit d4a584d

Browse files
committed
fix links
1 parent 05b1c16 commit d4a584d

16 files changed

Lines changed: 102 additions & 60 deletions

File tree

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
"ui": patch
3+
---
4+
5+
Refactor navigation to use TanStack Router best practices
6+
7+
- Replace internal navigation `<a>` tags with `<Link>` components for automatic intent-based preloading
8+
- Remove `as never` type casts from route definitions to restore proper TypeScript inference
9+
- Fix route param types for dynamic routes (organizations, projects, apps)
10+
- Fix optional search params type inference for `/apps` route
11+
- Improve type safety and autocomplete for route navigation
12+
- Preserve external links as `<a>` tags (API endpoint, external domains, static files)
13+
14+
This enables automatic route preloading on hover/focus, improving navigation performance and user experience.

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ jobs:
5555
- name: Create GitHub Releases
5656
if: steps.changesets.outputs.hasChangesets == 'false'
5757
run: |
58-
for pkg in api ui; do
58+
for pkg in api ui host; do
5959
VERSION=$(jq -r '.version' "$pkg/package.json")
6060
TAG="$pkg@$VERSION"
6161

package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,7 @@
4242
"dev:api": "bun packages/everything-dev/cli.js dev --ui remote",
4343
"dev:proxy": "bun packages/everything-dev/cli.js dev --proxy",
4444
"build": "bun packages/everything-dev/cli.js build",
45-
"build:api": "bun run --cwd api build",
46-
"build:ui": "bun run --cwd ui build",
47-
"deploy": "DEPLOY=true NODE_ENV=production bun run build:ui && bun run build:api",
45+
"deploy": "bun packages/everything-dev/cli.js build --deploy",
4846
"publish": "bun packages/everything-dev/cli.js publish",
4947
"sync:api-contract": "bun packages/everything-dev/src/scripts/sync-api-contract.ts",
5048
"typecheck": "bun run sync:api-contract && bun run --cwd ui tsc --noEmit && bun run --cwd api tsc --noEmit",

ui/src/components/user-nav.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,9 @@ export function UserNav() {
9595
<Link to="/settings">settings</Link>
9696
</DropdownMenuItem>
9797
<DropdownMenuItem asChild>
98-
<a href="/apps">published apps</a>
98+
<Link to="/apps" search={{}}>
99+
published apps
100+
</Link>
99101
</DropdownMenuItem>
100102
{user.role === "admin" && (
101103
<DropdownMenuItem asChild>
@@ -135,7 +137,9 @@ function DotControl() {
135137
<Link to="/login">connect</Link>
136138
</DropdownMenuItem>
137139
<DropdownMenuItem asChild>
138-
<a href="/apps">apps</a>
140+
<Link to="/apps" search={{}}>
141+
apps
142+
</Link>
139143
</DropdownMenuItem>
140144
<DropdownMenuItem asChild>
141145
<Link to="/about">about</Link>

ui/src/routes/_layout.tsx

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ function Layout() {
6767
<aside className="hidden sm:flex shrink-0 w-16 flex-col items-center border-r border-border bg-card py-4 gap-1.5 overflow-y-auto animate-fade-in">
6868
<Tooltip>
6969
<TooltipTrigger asChild>
70-
<a
71-
href="/"
70+
<Link
71+
to="/"
7272
aria-label="everything.dev home"
7373
className="mb-3 flex items-center justify-center w-10 h-10 border-2 border-outset border-[rgb(51,51,51)] dark:border-[rgb(100,100,100)] bg-card shadow-sm transition-shadow duration-200 hover:shadow-md"
7474
>
@@ -81,7 +81,7 @@ function Layout() {
8181
<title>everything.dev</title>
8282
<circle cx="12" cy="12" r="10" />
8383
</svg>
84-
</a>
84+
</Link>
8585
</TooltipTrigger>
8686
<TooltipContent side="right">everything.dev</TooltipContent>
8787
</Tooltip>
@@ -95,9 +95,9 @@ function Layout() {
9595
return (
9696
<Tooltip key={item.label}>
9797
<TooltipTrigger asChild>
98-
<a href={item.to} className={className}>
98+
<Link to={item.to} className={className}>
9999
<Icon className="w-4 h-4" />
100-
</a>
100+
</Link>
101101
</TooltipTrigger>
102102
<TooltipContent side="right">{item.label}</TooltipContent>
103103
</Tooltip>
@@ -129,10 +129,10 @@ function Layout() {
129129
<div className="flex items-center justify-between px-4 sm:px-6 h-12">
130130
{isAuthenticated ? (
131131
<div className="flex items-center gap-2 text-xs text-muted-foreground font-mono min-w-0">
132-
<a
132+
<Link
133133
aria-label="everything.dev home"
134134
className="sm:hidden flex items-center justify-center w-8 h-8 border-2 border-outset border-[rgb(51,51,51)] dark:border-[rgb(100,100,100)] bg-card shadow-sm transition-shadow duration-200 hover:shadow-md"
135-
href="/"
135+
to="/"
136136
>
137137
<svg
138138
viewBox="0 0 24 24"
@@ -143,7 +143,7 @@ function Layout() {
143143
<title>everything.dev</title>
144144
<circle cx="12" cy="12" r="10" />
145145
</svg>
146-
</a>
146+
</Link>
147147
<div className="hidden sm:flex items-center gap-2">
148148
<span>everything.dev</span>
149149
<span>/</span>
@@ -207,10 +207,10 @@ function Layout() {
207207

208208
if (item.to) {
209209
return (
210-
<a key={item.label} href={item.to} className={className}>
210+
<Link key={item.label} to={item.to} className={className}>
211211
<Icon className="w-4 h-4" />
212212
<span className="text-[10px]">{item.label}</span>
213-
</a>
213+
</Link>
214214
);
215215
}
216216

ui/src/routes/_layout/_authenticated/home.tsx

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,9 @@ function Home() {
124124
<Link to="/organizations">organizations</Link>
125125
</Button>
126126
<Button asChild variant="outline">
127-
<a href="/apps">published apps</a>
127+
<Link to="/apps" search={{}}>
128+
published apps
129+
</Link>
128130
</Button>
129131
</div>
130132
</CardContent>
@@ -243,7 +245,9 @@ function Home() {
243245
</div>
244246
<div className="flex flex-wrap gap-2">
245247
<Button asChild size="sm">
246-
<a href={`/organizations/${encodeURIComponent(activeOrg.id)}`}>open org</a>
248+
<Link to="/organizations/$id" params={{ id: activeOrg.id }}>
249+
open org
250+
</Link>
247251
</Button>
248252
{organizations.length > 1 && (
249253
<Button
@@ -284,7 +288,7 @@ function Home() {
284288
</p>
285289
</div>
286290
<Button asChild variant="outline" size="sm">
287-
<a href="/projects/new">new project</a>
291+
<Link to="/projects/new">new project</Link>
288292
</Button>
289293
</div>
290294

@@ -309,12 +313,13 @@ function Home() {
309313
</Badge>
310314
<Badge variant="outline">{project.visibility}</Badge>
311315
</div>
312-
<a
313-
href={`/projects/${project.id}`}
316+
<Link
317+
to="/projects/$id"
318+
params={{ id: project.id }}
314319
className="font-medium hover:underline break-all"
315320
>
316321
{project.title}
317-
</a>
322+
</Link>
318323
{project.description && (
319324
<p className="text-xs text-muted-foreground line-clamp-2">
320325
{project.description}
@@ -333,7 +338,7 @@ function Home() {
333338
No projects yet. Create your first project to start organizing apps.
334339
</p>
335340
<Button asChild variant="outline" size="sm">
336-
<a href="/projects/new">create project</a>
341+
<Link to="/projects/new">create project</Link>
337342
</Button>
338343
</CardContent>
339344
</Card>
@@ -351,7 +356,9 @@ function Home() {
351356
</Button>
352357
{activeOrgId ? (
353358
<Button asChild variant="outline" size="sm">
354-
<a href={`/organizations/${encodeURIComponent(activeOrgId)}`}>invite member</a>
359+
<Link to="/organizations/$id" params={{ id: activeOrgId }}>
360+
invite member
361+
</Link>
355362
</Button>
356363
) : (
357364
<Button variant="outline" size="sm" disabled>
@@ -367,7 +374,9 @@ function Home() {
367374
</Button>
368375
)}
369376
<Button asChild variant="outline" size="sm">
370-
<a href="/apps">open registry</a>
377+
<Link to="/apps" search={{}}>
378+
open registry
379+
</Link>
371380
</Button>
372381
</div>
373382
</section>

ui/src/routes/_layout/_authenticated/organizations/$id.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ const orgApiKeysQueryOptions = (orgId: string) =>
4444
apiClient.listApiKeys({ organizationId: orgId }),
4545
});
4646

47-
export const Route = createFileRoute("/_layout/_authenticated/organizations/$id" as never)({
47+
export const Route = createFileRoute("/_layout/_authenticated/organizations/$id")({
4848
loader: async ({
4949
context,
5050
params,

ui/src/routes/_layout/_authenticated/organizations/index.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,9 @@ function OrganizationsList() {
132132

133133
<div className="flex flex-wrap gap-2">
134134
<Button asChild size="sm">
135-
<a href={`/organizations/${encodeURIComponent(org.id)}`}>open org</a>
135+
<Link to="/organizations/$id" params={{ id: org.id }}>
136+
open org
137+
</Link>
136138
</Button>
137139
{!isActive && (
138140
<Button

ui/src/routes/_layout/_authenticated/settings.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ function Settings() {
7373
<Link to="/home">back to workspace</Link>
7474
</Button>
7575
<Button asChild variant="outline">
76-
<a href="/apps">published apps</a>
76+
<Link to="/apps" search={{}}>
77+
published apps
78+
</Link>
7779
</Button>
7880
</div>
7981
</CardContent>

ui/src/routes/_layout/apps/$accountId.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { useQuery } from "@tanstack/react-query";
2-
import { createFileRoute } from "@tanstack/react-router";
2+
import { createFileRoute, Link } from "@tanstack/react-router";
33
import { apiClient } from "@/app";
44
import { Badge, Button, Card, CardContent } from "@/components";
55

6-
export const Route = createFileRoute("/_layout/apps/$accountId" as never)({
6+
export const Route = createFileRoute("/_layout/apps/$accountId")({
77
head: ({ params }) => ({
88
meta: [
99
{ title: `${(params as { accountId: string }).accountId} | Published Apps | everything.dev` },
@@ -32,9 +32,9 @@ function AccountAppsPage() {
3232
<div className="space-y-8">
3333
<section className="space-y-4">
3434
<div className="flex flex-wrap items-center gap-2 text-xs font-mono text-muted-foreground">
35-
<a href="/apps" className="hover:text-foreground transition-colors">
35+
<Link to="/apps" search={{}} className="hover:text-foreground transition-colors">
3636
apps
37-
</a>
37+
</Link>
3838
<span>/</span>
3939
<span>{accountId}</span>
4040
</div>
@@ -87,7 +87,9 @@ function AccountAppsPage() {
8787
<CardContent className="p-8 text-center space-y-3">
8888
<p className="text-sm">No published gateways were found for this account.</p>
8989
<Button asChild variant="outline" size="sm">
90-
<a href="/apps">back to registry</a>
90+
<Link to="/apps" search={{}}>
91+
back to registry
92+
</Link>
9193
</Button>
9294
</CardContent>
9395
</Card>

0 commit comments

Comments
 (0)