Storyblok
Search Storyblok's Documentation
  1. Dynamic Routing in Vue

Dynamic Routing in Vue

Set up a catch-all route strategy in your Vue project to render new stories dynamically.

Setup

Install the vue-router package in the terminal.

npm install vue-router

Fetch a story dynamically

Create a PageView.vue file to fetch any story within your Space.

src/PageView.vue
<script setup>
import { useStoryblok } from '@storyblok/vue';
import { useRoute } from 'vue-router'

const slug = useRoute().params.slug
const story = await useStoryblok(`${slug ? slug : 'home'}`, {
	version: 'draft',
});
</script>

<template>
	<StoryblokComponent v-if="story" :blok="story.content" />
</template>

Get the slug from the current route, making an exception for our home story to be /.

Render all stories

In your main.js file, add the code to initialize and use the router.

src/main.js
import { createApp } from 'vue';
import { StoryblokVue, apiPlugin } from '@storyblok/vue';
import { createWebHistory, createRouter } from 'vue-router';
import App from './App.vue';
import Page from './components/Page.vue';
import Teaser from './components/Teaser.vue';
import Grid from './components/Grid.vue';
import Feature from './components/Feature.vue';
import PageView from './PageView.vue';

const routes = [
	{ path: '/', component: PageView },
	{ path: '/:slug', component: PageView },
];
	
const router = createRouter({
	history: createWebHistory(),
	routes,
});
		
const app = createApp(App);
		
app.use(StoryblokVue, {
	accessToken: import.meta.env.VITE_STORYBLOK_DELIVERY_API_TOKEN,
	use: [apiPlugin],
});
		
app.component('Page', Page);
app.component('Teaser', Teaser);
app.component('Grid', Grid);
app.component('Feature', Feature);
app
	.use(router)
	.mount('#app');

Vue Router requires us to specify a home route or it will not resolve it.

Replace the HomeView component for the RouterView one from vue-router.

src/App.vue
<script setup>
	import Home from './Home.vue';
</script>

<template>
	<main>
		<Suspense>
			<template #default>
				<Home />
				<RouterView />
			</template>
		</Suspense>
	</main>
</template>

With this approach, your project can automatically handle new stories you add to your Space.

Remove the Home.vue content file from the project.