How to create a scheduled component using Vue.js?
Storyblok is the first headless CMS that works for developers & marketers alike.
With Vue.js it is unbelievably easy to render dynamic components, which we can utilize to render content with specific components and layouts by only using their name.
We've already covered the topic on how to render component dynamically from a JSON, now we will focus on how to only render components if in the correct time frame.
The JSON structure
The content JSON has been enhanced by a new component called schedule
which consists of a field start
, end
and body
field. The start
and end
property in our example are not required and can result in an empty string. Each DateTime string is in GMT+0 just so we get the question about timezones out of our mind for this.
Filtering before or during looping through components?
We now have two possibilities on how to receive the components we want to actually how. In this small example filtering the components beforehand will be much easier by using a computed property, however with a nested and more complex content structure that might already be way harder as you no longer loop through one array of objects but a tree content structure instead.
Looping through the component tree
Filtering dates in JavaScript is always a bit tricky, packages like momentjs make things easier. If you're performing more complex date operations it's good to know they exist, for this example we'll use the default Date
of JavaScript and add the timezone +0000
before using the date strings. To use a method and the Vue.js template instead of using a computed property we extract the above filter method into a helper method, let us call it isComponentVisible
.
Since we're not going to use the computed property we can return to our direct content structure using content.body
.
The last step to filter our components is to use the isComponentVisible
method with the current block
object.
When should I use which approach?
We would recommend opting for the method approach as you can outsource that one method from your component and re-use it everywhere (where component
might be used) in your Vue.js app. This way you no longer have the complexity of filtering out the components of the structure before rendering, but decide during rendering what to show.
Keep in mind that even tho the components are not displayed we would recommend to only use this approach with non-sensitive information. Your data is filtered on the client and the original information is still available through the browsers dev tools.
If you want to filter information before rendering on the client you would be able to use a server-side rendered website or a static site generator. Another option would be to go for a cloud function / custom API (Netlify Function / Vercel) to filter your component on a server.
Editing the JSON
Adding a new component called schedule
to wrap around your other components will allow you to not have to add fields (start, end) on every component, but only one those that you need. Adding a start
and end
field to the schedule
component can be done by pressing Define Schema in that component and adding two new fields. Select the type Date/Time and you're ready to go. Next, to allow nesting of components, we will also create a field called body
with the field type Blocks. This will allow you to nest your previous components (in our example: foo and bar) in it. Try it out by exchanging the static content with our demo API Call right here.
The Schedule Components code
The schedule component itself uses the same set-up as our page component. If you want to allow schedule components in scheduled components you can again use the same isComponentVisible
set-up. Loop over your components in the "body" field and include the components as you go.