Skip to content

Dynamic Routing in Vue

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

Install the vue-router package in the terminal.

Terminal window
npm install vue-router

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.join('/') : '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 /.

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: '/: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');

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.