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_ACCESS_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 your project, as it’s not needed.