Anchor tags with scroll effect in Nuxt 3
Tags: webdev, beginners, vue, nuxt
Published: 2023-02-15 16:40:59

Building a Single Page Application in Nuxt 3 is quite simple. Every SPA requires links with anchor tags to navigate to sections of the page. That's easy to achieve with an `<a>` tag with an `href='#anchor'` attribute that specifies where your link should navigate to.

In Nuxt, I set this up by using `NuxtLink` with a `path` and a `hash`. For instance, this is written in a `Navigation.vue` file.
![NuxtLink with a hash](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c8cs0paduv8h0boea3ek.png)

Following that, I have a different file probably named `WhateverSection.vue`. In this section, add an `id` that is the same name as the one given in our `hash`. 
![Template with section](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9jn07xoxa1l5jjql9np6.png)

This should already work. However, it just navigates to a section without any scrolling effect. A nice and smooth scroll effect is important for a pleasant user experience. That is what we would like to accomplish here. 

[Nuxt 2](https://nuxtjs.org/docs/components-glossary/scrolltotop/) has a `scrollToTop` & `scrollBehavior` option which isn't available (_yet_) in Nuxt 3. At least, none of the documentation I read mentioned it. 

Another option would be to make use of the `scrollIntoView()` HTML function, but that doesn't help achieve my goal of adding a scroll effect. 

With a little research, I figured I wasn't the only one that encountered this little issue in Nuxt 3. 

Here are the steps I followed to achieve this.

First, we have to create a `/plugin` folder for our application and a `router.ts` file to contain our code. 
![Folder structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xo16heu9bi69vro5irwx.png)

In Nuxt or Vue, [plugins](https://vuejs.org/guide/reusability/plugins.html) contain code that should run before a Vue app is created.
Nuxt automatically reads files in the [plugin directory](https://nuxt.com/docs/guide/directory-structure/plugins) so you don't have to worry about loading them directly into your app.

In `router.ts`, we would set it up with `defineNuxtPlugin` which basically informs your Nuxt app to create a new plugin. You then want to pass the `$router` which is an object from your Nuxt app, to give us access to the Vue router options on which we're about to expand. `ScrollBehavior` is part of [Vue's router options](https://router.vuejs.org/api/interfaces/RouterOptions.html#Properties-scrollBehavior)

![scroll behavior](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9z2y8ikh76yx4rr69tkb.png)

Here, you can set the hash you want to scroll to, where on the screen this section should be placed, and the type of behavior you expect when scrolling. 

With this, you can also expand on the plugin adding all sorts of fancy things you want to achieve when scrolling.

I wouldn't have been able to make this post without taking a good peak at the following links:
1. [this](https://github.com/lukaszflorczak/nuxt3-demo/tree/test/scroll-behavior/plugins) solution with the plugin folder structure
2. [this](https://github.com/nuxt/nuxt/issues/12732) issue that looked just like mine
3. [this](https://github.com/nuxt/nuxt/issues/12732#issuecomment-1397227098) response by Daniel Roe. In case you missed it, he gave a talk at [VueJs Amsterdam](https://vuejs.amsterdam/) about rapid development with Nuxt 3!
4. Photo by <a href="https://unsplash.com/@bagelsncoffee_?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Ryan Harper</a> on <a href="https://unsplash.com/photos/S8nT0awuFEU?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>