How to do component transitions between pages in NextJS? - javascript

I am trying to make a simple form that slides to the right like this one used by DigitalOcean when you click on "Sign up using email": https://cloud.digitalocean.com/registrations/new.
The transition itself is pretty easy, what caught my attention is that they use 2 separate routes for this, the first one under /new and the other one under /email. These 2 seem to be separate pages and not just 2 different states to which a route is programmatically added, how can I do this in NextJS?

I believe the feature that you're looking for is shallow routing.
From the Docs:
Shallow routing allows you to change the URL without running data
fetching methods again, that includes getServerSideProps,
getStaticProps, and getInitialProps.
You'll receive the updated pathname and the query via the router
object (added by useRouter or withRouter), without losing state.
Note, however, that:
[s]hallow routing only works for URL changes in the current page.
See also:
next/router - router.push()
Dynamic Routes
This answer by #metaaa may also shed some light re implementation.
Best of luck and happy coding!

Related

The recommended way to load route data before entering the route?

Before rendering a page for a given route, I'd like to synchronously fetch the necessary data first. Ideally, I'd like to have the data fetching within the page component, but I'm not opposed to doing it in the router files. I've read and tried various ways of doing it, but part of the challenge comes from the fact that there are also multiple ways of building components and the usage of certain features vary.
In my case, I'm building single file components using the Composition API and <script setup> syntax. The Vue Router documentation link talks about "fetching before navigation" in which I could reach for beforeRouteEnter or beforeRouteUpdate, but this is shown using the Options API. They do have the page for the Composition API mentioning I could use onBeforeRouteUpdate, but that uses the setup() function. I figured I'd try it out anyway with <script setup>:
<script setup>
import { onBeforeRouteUpdate } from 'vue-router'
onBeforeRouteUpdate(() => {
console.log('onBeforeRouteUpdate')
})
</script>
However, this does not execute. The closest method I've tried that works is fetching the data in the router, using the beforeEnter guard, and setting the data onto the meta property, which can then get accessed on the route instance in the component:
beforeEnter: (to, from, next) => {
fetch('https://pokeapi.co/api/v2/pokemon/ditto')
.then(res => res.json())
.then(res => {
to.meta.pokemon = res;
next();
});
}
But with this, which is noted in the documentation, beforeEnter only triggers when entering the route. Params changes will not retrigger this, meaning that I'd have to set up a watcher on the route in the component anyway. I might as well just have had all this logic in the component itself.
I just can't seem to find a good way to do this, but I might have overlooked something. If anyone has some pointers or advice, I'd appreciate it. Thanks in advance.
There is a solution - using top level await - https://vuejs.org/api/sfc-script-setup.html#top-level-await
Just wrap your RouterView component in a Suspense component like shown here - https://vuejs.org/guide/built-ins/suspense.html#combining-with-other-components (don't use the components you don't need)
The only caveat is that the 'loading screen' will be visible on the initial request.
I made a little demo for you so you can try it out - https://github.com/ileue/vue-top-level-await-demo
First off, beforeRouteUpdate is only triggered when updating the actual route but not going to another component/page as officially told here.
An example on what could trigger that lifecycle hook would be
<button #click="$router.push({ hash: `#${Math.floor(Math.random() * 10)}` })">
random hash
</button>
onBeforeRouteLeave perfectly works tho, as you can expect, when moving from page to page.
As for the initial question, you could implement some kind of router middleware like Nuxt does it. That way, you could await an HTTP call and only then allow for an actual navigation. Hence creating a block navigation effect pretty much.
I'm not sure on how to write that with Composition API, but I know that it perfectly works with Options API (quite some blog posts available). setup by itself behaving in it's own life-cycly way, I guess quite some things are rather tricky.
TLDR: a good ol' router middleware + wrapper around your pages (like a layout) is the perfect combo in your case IMO. There, you could set a single watcher for quite a lot of pages at the same time.
But everything depends on how you want to organize yourself and structure your code of course.
Skeleton screens bring a sense of being faster than something blocking but overall, you could also use prefetch (coming with Nuxt too by default) to get some hints and potentially load some assets even before they are needed. (+ other tricks in the same domain to speed up your network requests)

Mimicking react-router-dom Nested Routes in Next.js

I am trying to mimic this example from react-router. I dug through some issues on GH and it doesn't seem possible. At the same time, though, isn't this something that is basic/common among web apps? Am I missing something obvious?
My current structure is:
/pages
/session
[sid].js
/topics
[tid].js
The session page has a list of topics that I want to update on the [sid].js page. However, everything I tried just navigates to [tid].js. I've tried using <Link> with replace but this doesn't do what I want because I do still want the item in history. I tried router.push but I'm in the same boat and would really like to use a <a> element.

Is it possible to reload the router in a running ember.js app in order to update the path strings of routes?

I'm implementing multi-language support in my app, and I guess this is the last thing that I would need in order to be able to change between languages without reloading the whole app/page. (I already have a solution with full page reload.)
For a simple example let's say this is how my router looks:
Router.map(function() {
this.route('search', { path: t('search') });
this.route('item', { path: `${t('item')}/:id`);
});
The t function would be getting the correct translation for the given strings in the currently active language.
The structure of the route hierarchy won't change, the only things that need to be updated are the path strings. Application state should be kept, of course.
I'm wondering whether this is possible to do.
I am not %100 sure about the correctness of what I wrote but Router.map is executed and resources with the definitions given within this method is transformed to a DSL instance and that is then passed to the actual router maintained by Ember.Router itself. In order to achieve what you want I believe what we need is dynamic modification to the router even if it is just the paths you need yo modify not the whole route structure.
If you look at the following github issue, Ember.js no more supports dynamically adding routes (hence no dynamic modification to the existing ones I believe). With all that said, I believe what you want is not possible without reloading the whole app (hence losing the application state).

Marionette - triggering actions from controllers

I'm trying to understand all the logic behind routers and controllers in Marionette. As you can see below each example is using different approach to handle the triggering actions mechanism,so it's really hard to decide which approach should I be using.
example - link - this one renders the views from the APpController
example - link - uses Marionette.EventAggregator
example - link - uses the App instance to trigger all the actions.
It's also worth mentioning that most of them are 2-3 years old hence I'm asking my self whether or not use them in my app.
I have created a basic Marionette.AppRouter and Marionette.Controller inside my Marionette.Application instance. All the defined routes in my AppRouter module are working correctly. So I wanted to go further and update one of my views once the "#home" route is fired. But I was unable to do so, as after reading all the docs, it was still not clear to me how to update all my views from the AppController?
Should I use EventAggregator for all the communication between AppController and Marionette.Applicaiton ?
Should I define my LayoutView including ItemViews..etc in my AppController ?
Or should I just pass an instance of my App to AppController?
I' would be really glad if someone pointed me to a simple, up-to-date (AMD) example.
The newest way is Backbone.Radio. It will be the default event manager in the next big version of Marionette. You can shim it into the latest version and use it today.
Personally I decided on using Radio together with a custom made router. There are conflicting opinions on how to organize everything but I kept both radio and the router outside of the scope of Marionette.Application (window.radio, window.router, window.app). It works well and can be another viable option.

Backbone routes: Before & after hooks?

I'm trying to add the equivalent of rails' "flash" functionality in my backbone app, part of which involves putting a showFlash() at the top of each route in my router, and a purgeFlash() at the bottom.
Needless to say, adding those two methods to every route works, but it isn't the most elegant approach. Still, I'm struggling to figure out how to add hooks to backbone routers.
In short, I'd like to run showFlash() before navigating to any new page, and purgeFlash() afterwards. ...Any thoughts?
This plugin should do the trick:
https://github.com/angelo0000/backbone_filters
(not sure though if it works with the latest backbone version)
update - according to this comment it works with 0.9.2

Categories