Skip to main content

Dynamic Routes

Dynamic routes allow you to create flexible URL patterns that accept parameters. This is essential for pages like user profiles, blog posts, or product details.

Dynamic Segments

Use square brackets [param] in your file name to create a dynamic route segment:

Basic Example

app/user/[id].tsx
Matches:
  • /user/123{ id: '123' }
  • /user/alice{ id: 'alice' }
  • /user/admin-2024{ id: 'admin-2024' }

Accessing Parameters

Use the useLocalSearchParams() hook to access route parameters:
From the source (hooks.ts:244-314):

Type-Safe Parameters

Add TypeScript types for type safety:
app/user/[id].tsx

Multiple Dynamic Segments

Create routes with multiple parameters:
app/blog/[category]/[slug].tsx
Matches:
  • /blog/tech/expo-router-guide{ category: 'tech', slug: 'expo-router-guide' }
  • /blog/design/ui-patterns{ category: 'design', slug: 'ui-patterns' }

Query Parameters

Access query parameters alongside route parameters:
app/search/[query].tsx
URL: /search/react?filter=recent&sort=popular Params: { query: 'react', filter: 'recent', sort: 'popular' }

Catch-All Routes

Use [...param] to match multiple segments:

Basic Catch-All

app/docs/[...slug].tsx
Matches:
  • /docs/getting-started{ slug: ['getting-started'] }
  • /docs/api/reference{ slug: ['api', 'reference'] }
  • /docs/guides/routing/dynamic{ slug: ['guides', 'routing', 'dynamic'] }

Practical Catch-All Example

app/docs/[...slug].tsx

Using Router

Dynamic List Example

app/users/index.tsx

Optional Segments

Create optional dynamic segments with catch-all:
app/shop/[[...category]].tsx
Matches:
  • /shop{ category: undefined }
  • /shop/electronics{ category: ['electronics'] }
  • /shop/electronics/phones{ category: ['electronics', 'phones'] }

Array Parameters

Handle array parameters from query strings:
app/products/index.tsx
URL: /products?tags=new&tags=sale&tags=featured Params: { tags: ['new', 'sale', 'featured'] }

URL Encoding

Parameters are automatically URL encoded/decoded:
From the source (hooks.ts:286-311):

Updating Parameters

Update route parameters without navigation:

Global vs Local Params

useLocalSearchParams()

Updates only when the screen is focused:

useGlobalSearchParams()

Updates even when screen is not focused:
From the source (hooks.ts:210-242):

Route Specificity

When multiple routes could match, Expo Router uses specificity:
Specificity order (highest to lowest):
  1. Exact matches: new.tsx
  2. Dynamic routes: [id].tsx
  3. Catch-all routes: [...all].tsx
Example:
  • /productsindex.tsx
  • /products/newnew.tsx (exact match wins)
  • /products/123[id].tsx with { id: '123' }
  • /products/category/phones[...all].tsx with { all: ['category', 'phones'] }

Best Practices

Use Descriptive Parameter Names

Validate Parameters

Handle Missing Parameters

Type All Parameters

Common Patterns

Pagination

app/posts/index.tsx

Tabs with Parameters

app/profile/[userId].tsx

Filtering and Sorting

app/products/index.tsx

Next Steps

Layouts

Share UI across dynamic routes

Typed Routes

Type-safe dynamic routes

Deep Linking

Deep link to dynamic routes

API Routes

Create dynamic API endpoints