View Transitions API hands on examples of utilization (Nuxt3, Vue3)

View Transitions API hands on examples of utilization (Nuxt3, Vue3)

For anyone who is less familiar: the View Transitions API (VTA) provides a mechanism for easily creating animated transitions between different DOM states, while also updating the DOM contents in a single step. View transitions are a popular design choice for reducing users' cognitive load, helping them stay in context, and reducing perceived loading latency as they move between states or views of an application.

Transitions between states in single-page apps (SPAs) tends to involve writing significant CSS and JavaScript, which complicates many things, including a11y, unless using popular libraries for React/Angular/Vue animations, which will do many things for you under the hood but often are not working with native DOM elements, but rather doing some funky stuff.

The transition effect is achieved by taking a snapshot, a sort of image, of the site in its current state and another snapshot of the incoming page and then allowing animations between them. Simple fades and whole page transitions (like in my example) are fairly straightforward but more complex looks can be achieved by breaking the snapshot up into named layers and animating those separately.

I wont go here into exactly how VTA works in of itself, you can check this LINK to mozilla if you want to get into the grits of things (it is very useful to understand), but rather I will show and give few examples on how to understand and utilize its power.

For React: as long as the used browser supports the view transition api, react-router would startViewTransition on navigation and trigger any transition if implemented in CSS.

For Angular: this ARTICLE by Konstantine Denerz gives a decent explanation on how to implement VTA with Angular environment.

I will focus on Vue3/Nuxt3 implementation as I am to see yet any guides or break downs on this for anyone newer to this technology. I will do my best to make things as concise and to-the-point as possible without losing the value.

So, for starters, since the merge of this ISSUE and few new releases to Nuxt3, VTA is supported as an experimantal feature, that said, I have not seen any issue in its operation yet as Restless Beings Nuxt3 app that is currently in development will run on VTA transitions on both pages and DOM elements where desired (already runs in Dev). The way we enable VTA in Nuxt3 right now is by adding

experimental: {
  jsTsFormatResource: true,
  viewTransition: true,
},        

viewTransition: true into experimental object in our nuxt.config.ts

This will be enough to enable basic fade out page transitions. Simple enough, isn't it?

Next thing, let's say we have an img banner that when clicked we want to expand to a bigger size while the page transition happens. To get this done, we will need to give this img a name in our CSS (<style> section) with a special key, example:

<style scoped>
		
img {
		
  view-transition-name: selected-appeal;
		
}
		
</style>        

And then do the same for the img tag that we want the animation to finale at the end of animation and page transition. It will most likely be the same img just in a different page to our routing to and have bigger width and height. VTA is smart enough to make a nice zoom transition by itself. So the example code for the page you are transitioning to will look something like this:

<style scoped>
		
img.active {
		
  view-transition-name: selected-appeal;
		
  contain: layout;
		
}
		
</style>        

You will need contain: layout in there in order for VTA to know exactly what content to transition-animate. Also most likely if you are looping through an array of images on the original page( not destination page), you will need to make a simple ref with boolean value that in case of a click on a specific image will help VTA to understand what image it needs to transition-animate. Example:

 :class="{ active: active === appeal.objectID }
		
 @click="active = appeal.objectID""        

And that's all you need to make it happen using some CSS!

Last but not least thing I would like to unpack here is startViewTransition function. There are OFFICIAL DOCS on this and basic show cases, I find them not very straightforward personally. Here is an example of my usage on this functionality. Many things can be done with it, simple and complex.

<script setup lang="ts">
const options: Map<string, string> = new Map();
options.set("first", "reports");
options.set("second", "appeals");

const optionDisplayed = ref(options.get("first"));
const changeOption = () => {
  if (!document.startViewTransition) {
    if (optionDisplayed.value === options.get("first")) {
      optionDisplayed.value = options.get("second");
    } else {
      optionDisplayed.value = options.get("first");
    }
    return;
  }
  document.startViewTransition(() => {
    if (optionDisplayed.value === options.get("first")) {
      optionDisplayed.value = options.get("second");
    } else {
      optionDisplayed.value = options.get("first");
    }
    return;
  });
};
</script>        

Core principle here is to select 2 elements that you want to have animate during the transition and write a logic of what you want to happen when the event fires and when the transition is over.

Something to remember, have a fallback for older browsers that may not support VTA by providing an if statement alternative:

function spaNavigate(data) {
  // Fallback for browsers that don't support this API:
  if (!document.startViewTransition) {
    updateTheDOMSomehow(data);
    return;
  }

  // With a transition:
  document.startViewTransition(() => updateTheDOMSomehow(data));
}        

Thank you for reading and hopefully this brought you the value I intended.

Happy coding.

To view or add a comment, sign in

More articles by Yuri Arri Avdijevski

  • Advanced Caching Guide in Nuxt3

    Coming across a couple of articles, including Mastering Nuxt course, which state that caching does not come with Nuxt3…

  • Storybook for Nuxt 3 with Vite and TypeScript

    Over the last couple of days, I spent a lot of time configuring Storybook work with Nuxt3 and Vite. I took me roughly 3…

    1 Comment

Others also viewed

Explore content categories