useRoute() | Vue Router
useRoute() is a composition API function that provides access to the current route object. This function returns a reactive object containing information about the current route, including params, query, hash, and other route-specific data. 📍
📋 Function Signature
typescript
function useRoute(): RouteLocationNormalizedLoaded🎯 Purpose and Functionality
The useRoute() function gives you access to the current active route information in a reactive way. Any changes to the route (like parameter changes or query updates) will trigger reactivity in your component.
Key Information Available:
- ✅ Route Parameters - Dynamic segments like
/user/:id - ✅ Query Parameters - URL query string values
- ✅ Route Meta Information - Custom metadata attached to routes
- ✅ Route Matching Details - Information about matched routes
- ✅ Hash Fragment - URL hash value
📤 Return Value
Returns a reactive RouteLocationNormalizedLoaded object containing all information about the current route.
💡 Basic Usage Examples
Accessing Route Parameters
vue
<template>
<div>
<h1>User Profile: {{ userID }}</h1>
<p>Query parameter: {{ searchQuery }}</p>
</div>
</template>
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
// Access route parameters reactively
const userID = computed(() => route.params.id)
// Access query parameters
const searchQuery = computed(() => route.query.q)
</script>Route Information Display
vue
<template>
<div>
<p>Current path: {{ route.path }}</p>
<p>Route name: {{ route.name }}</p>
<p>Full path: {{ route.fullPath }}</p>
</div>
</template>
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
</script>🔧 Advanced Usage Patterns
Watching Route Changes
vue
<script setup>
import { useRoute, watch } from 'vue-router'
const route = useRoute()
// Watch for specific parameter changes
watch(
() => route.params.id,
(newId, oldId) => {
console.log('User ID changed:', oldId, '→', newId)
loadUserData(newId)
}
)
// Watch query parameters
watch(
() => route.query.search,
(newSearch) => {
performSearch(newSearch)
}
)
// Watch entire route object for any changes
watch(route, (newRoute, oldRoute) => {
console.log('Route changed:', oldRoute.path, '→', newRoute.path)
})
</script>Conditional Rendering Based on Route
vue
<template>
<div>
<div v-if="isAdminRoute" class="admin-toolbar">
<AdminControls />
</div>
<main :class="{ 'admin-layout': isAdminRoute }">
<RouterView />
</main>
</div>
</template>
<script setup>
import { useRoute } from 'vue-router'
import { computed } from 'vue'
const route = useRoute()
const isAdminRoute = computed(() =>
route.path.startsWith('/admin')
)
const isEditMode = computed(() =>
route.name === 'user-edit' || route.query.mode === 'edit'
)
</script>Route Meta Information
vue
<script setup>
import { useRoute } from 'vue-router'
import { computed } from 'vue'
const route = useRoute()
// Access route meta information
const requiresAuth = computed(() =>
route.meta.requiresAuth === true
)
const pageTitle = computed(() =>
route.meta.title || 'Default Title'
)
const breadcrumbs = computed(() =>
route.meta.breadcrumbs || []
)
</script>🚨 Important Considerations
Reactivity and Route Changes
vue
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
// ✅ Correct - using computed for reactivity
const userId = computed(() => route.params.id)
// ❌ Incorrect - losing reactivity
const userId = route.params.id // Not reactive!
// ✅ Correct - watch for changes
watch(() => route.params.id, (newId) => {
// Handle ID change
})
// ✅ Correct - use in template directly (reactive)
// <div>{{ route.params.id }}</div>
</script>Type Safety with TypeScript
vue
<script setup lang="ts">
import { useRoute } from 'vue-router'
import type { RouteParams } from 'vue-router'
const route = useRoute()
// Type-safe parameter access
const userId = computed(() => {
// TypeScript will infer the correct type
return route.params.id as string
})
// For complex params, you can use type assertions
interface UserRouteParams {
id: string
tab?: string
}
const userParams = computed(() =>
route.params as UserRouteParams
)
</script>🔗 Related APIs
useRouter()- Access router instance for navigationRouteLocationNormalizedLoaded- Route object interface
📚 Route Object Properties
Core Properties
javascript
const route = useRoute()
// Basic route information
route.path // Current path (e.g., "/user/123")
route.fullPath // Full path with query and hash
route.name // Route name if defined
route.hash // URL hash fragment
// Parameters and query
route.params // Object containing route parameters
route.query // Object containing query parameters
// Meta information
route.meta // Custom metadata attached to the route
// Matching information
route.matched // Array of matched route recordsPractical Property Usage
vue
<script setup>
import { useRoute } from 'vue-router'
import { computed } from 'vue'
const route = useRoute()
// Common computed properties based on route
const currentSection = computed(() =>
route.path.split('/')[1] || 'home'
)
const hasQueryParams = computed(() =>
Object.keys(route.query).length > 0
)
const isActiveRoute = computed(() =>
route.name === 'target-route'
)
// Extract specific information
const pageNumber = computed(() =>
parseInt(route.query.page) || 1
)
const sortOrder = computed(() =>
route.query.sort || 'asc'
)
</script>💡 Practical Examples
Dynamic Page Title
vue
<script setup>
import { useRoute } from 'vue-router'
import { watch, ref } from 'vue'
const route = useRoute()
const pageTitle = ref('')
watch(route, (newRoute) => {
// Update page title based on route
if (newRoute.meta.title) {
pageTitle.value = newRoute.meta.title
document.title = `${newRoute.meta.title} - My App`
} else if (newRoute.name) {
pageTitle.value = String(newRoute.name).replace(/-/g, ' ')
document.title = pageTitle.value
}
}, { immediate: true })
</script>Search and Filter Implementation
vue
<template>
<div>
<input
v-model="searchTerm"
placeholder="Search..."
@input="updateSearch"
/>
<select v-model="selectedCategory" @change="updateCategory">
<option value="">All Categories</option>
<option v-for="cat in categories" :key="cat" :value="cat">
{{ cat }}
</option>
</select>
</div>
</template>
<script setup>
import { useRoute, useRouter } from 'vue-router'
import { ref, watch } from 'vue'
const route = useRoute()
const router = useRouter()
const searchTerm = ref(route.query.q || '')
const selectedCategory = ref(route.query.category || '')
// Update URL when filters change
const updateSearch = () => {
router.push({
query: {
...route.query,
q: searchTerm.value || undefined
}
})
}
const updateCategory = () => {
router.push({
query: {
...route.query,
category: selectedCategory.value || undefined
}
})
}
// Sync with route changes
watch(() => route.query.q, (newQ) => {
searchTerm.value = newQ || ''
})
watch(() => route.query.category, (newCategory) => {
selectedCategory.value = newCategory || ''
})
</script>Authentication and Route Protection
vue
<script setup>
import { useRoute, useRouter } from 'vue-router'
import { onMounted } from 'vue'
const route = useRoute()
const router = useRouter()
onMounted(() => {
// Check if current route requires authentication
if (route.meta.requiresAuth && !isAuthenticated()) {
// Redirect to login with return URL
router.push({
path: '/login',
query: { redirect: route.fullPath }
})
}
// Check user permissions for admin routes
if (route.path.startsWith('/admin') && !isAdmin()) {
router.replace('/access-denied')
}
})
</script>💡 Pro Tip: Use
watchwithimmediate: trueto handle both initial route values and subsequent changes in a single declaration.