Skip to content

RFC for a new Transition.waitFor method#1183

Open
frederikbosch wants to merge 8 commits into
emberjs:mainfrom
frederikbosch:main
Open

RFC for a new Transition.waitFor method#1183
frederikbosch wants to merge 8 commits into
emberjs:mainfrom
frederikbosch:main

Conversation

@frederikbosch
Copy link
Copy Markdown

@frederikbosch frederikbosch commented May 11, 2026

Propose Ember Router public Transition.waitFor method

Rendered

Summary

This pull request is proposing a new RFC.

To succeed, it will need to pass into the Exploring Stage, followed by the Accepted Stage.

A Proposed or Exploring RFC may also move to the Closed Stage if it is withdrawn by the author or if it is rejected by the Ember team. This requires an "FCP to Close" period.

An FCP is required before merging this PR to advance to Accepted.

Upon merging this PR, automation will open a draft PR for this RFC to move to the Ready for Released Stage.

Exploring Stage Description

This stage is entered when the Ember team believes the concept described in the RFC should be pursued, but the RFC may still need some more work, discussion, answers to open questions, and/or a champion before it can move to the next stage.

An RFC is moved into Exploring with consensus of the relevant teams. The relevant team expects to spend time helping to refine the proposal. The RFC remains a PR and will have an Exploring label applied.

An Exploring RFC that is successfully completed can move to Accepted with an FCP is required as in the existing process. It may also be moved to Closed with an FCP.

Accepted Stage Description

To move into the "accepted stage" the RFC must have complete prose and have successfully passed through an "FCP to Accept" period in which the community has weighed in and consensus has been achieved on the direction. The relevant teams believe that the proposal is well-specified and ready for implementation. The RFC has a champion within one of the relevant teams.

If there are unanswered questions, we have outlined them and expect that they will be answered before Ready for Release.

When the RFC is accepted, the PR will be merged, and automation will open a new PR to move the RFC to the Ready for Release stage. That PR should be used to track implementation progress and gain consensus to move to the next stage.

Checklist to move to Exploring

  • The team believes the concepts described in the RFC should be pursued.
  • The label S-Proposed is removed from the PR and the label S-Exploring is added.
  • The Ember team is willing to work on the proposal to get it to Accepted

Checklist to move to Accepted

  • This PR has had the Final Comment Period label has been added to start the FCP
  • The RFC is announced in #news-and-announcements in the Ember Discord.
  • The RFC has complete prose, is well-specified and ready for implementation.
    • All sections of the RFC are filled out.
    • Any unanswered questions are outlined and expected to be answered before Ready for Release.
    • "How we teach this?" is sufficiently filled out.
  • The RFC has a champion within one of the relevant teams.
  • The RFC has consensus after the FCP period.

@github-actions github-actions Bot added the S-Proposed In the Proposed Stage label May 11, 2026
@featheredtoast
Copy link
Copy Markdown

The alternative suggestion I had for awaiting routeWillChange methods (as they are written today) is if these methods don't return a promise, there would be nothing to wait for.

It also is similar to how Ember (before/after) model hooks work:
https://guides.emberjs.com/release/routing/asynchronous-routing/#toc_the-router-pauses-for-promises

If the model hook (or the related beforeModel or afterModel hooks) return normal (non-promise) objects or arrays, the transition will complete immediately. But if the model hook (or the related beforeModel or afterModel hooks) returns a promise... the transition will pause until that promise fulfills or rejects.

@frederikbosch
Copy link
Copy Markdown
Author

I have thought of this, the RFC mentions this as alternative solution.

An alternative solution to the waitFor method would be let the router await routeWillChange listeners. But with probably many listeners being used by current users, it is hard to foresee if this would break current applications. A new method allows users to opt-in to an asynchronous switch between old and new route.

And later

Alternatives are already discussed within the design and include awaiting routeWillChange listeners. This alternative has not beed chosen because the author of this RFC cannot foresee if this would break current applications.

If the consensus is going to be that routeWillChange should be awaited, if applicable, then I am happy to create a PR for that. In the RFC I have chosen a new method for aforementioned reasons.

@featheredtoast
Copy link
Copy Markdown

All good, I saw that - I just wanted to mention why it could possibly be a preferred route for RFC reviewers+maintainers.

@evoactivity
Copy link
Copy Markdown

The router and base route class is currently being redesigned, any kind of changes to router.js is going to end up being thrown away in the not so distant future.

Introducing this as a concept, updating guides and teaching it feels like it would be wasted effort as it will all be replaced soon, possibly for something very different, so we risk adding churn here.

I could be convinced it's worth having something in place in the interim, but I do lean more on the side that this could be done in app code for people who really want to use view transitions now without needing to land and shepherd a change at the framework level. A general solution that extends the current base route could be shared as an addon.

I'd be interested in the opinions of @ef4, @mansona and @nickschot.

@frederikbosch
Copy link
Copy Markdown
Author

Introducing this as a concept, updating guides and teaching it feels like it would be wasted effort as it will all be replaced soon, possibly for something very different, so we risk adding churn here.

I agree with this statement, as I have also explained in the RFC:

A drawback might be that #1169 is considered that might replace the current Ember Router with a new one. However, there is a need within the Ember community right now to implement view transitions in a non-hacky manner.

However, the adoption of this "very different" new router by the Ember user-base could be years, while the View Transition API improves user experience today and therefore something that developers are demanding right now.

Moreover, I would like to address that this just started as a PR to the original router.js library. That was before the library was integrated into the Ember repository.

This RFC doe snot request the introduction of a concept, updating guides and teaching in any direction. That would indeed be a waste of effort. I am requesting to add one public method. A method that does not break current applications. It could be addressed with a simple mention in the changelog and become available in the API documentation.

@frederikbosch
Copy link
Copy Markdown
Author

I could be convinced it's worth having something in place in the interim, but I do lean more on the side that this could be done in app code for people who really want to use view transitions now without needing to land and shepherd a change at the framework level. A general solution that extends the current base route could be shared as an addon.

There is - according my research - no way to integrate a generic View Transition API solution in app code, or to do this as an addon. With 'generic View Transition API solution' I mean a generic method to hook into every route change and apply the View Transition API to the Ember route transition.

The reasons is that the beforeModel hook is the first async awaited method after the creation of the route promise, and that hook is - of course - already of the new route. That would mean you would need to hack into the new route to await some promise that you created earlier on. So if you create the the document.startViewTransition in an routeWillChange listener, you can await the view transition promises firstly inside beforeModel. Moreover, you need to find a way to deliver this promise to that beforeModel hook. Before my PR @ router.js I used a custom undefined property on the transition as delivery mechanism. However, this separation (create in routeWillChange and await in beforeModel) makes things extremely complicated.

Another solution might be to create the the view transition before creating the ember transition, e.g. by creating a manual link-to component. That would require to replace current <LinkTo> usages. Besides, there are many more locations where transition are be created. You would need to implement a different service than the router service in those locations. It would require a huge effort to implement.

That is why the proposed single additional method is a very safe method right now, for those people that need it, to implement the View Transition API. It delivers a very clean API to implement the View Transition API in a generic manner right now, until there is something better that we can teach the global Ember user-base.

router.on('routeWillChange', async (transition) => {
  const { promise, resolve, reject } = Promise.withResolvers();
  transition.waitFor(promise);

  const viewTransition = document.startViewTransition(async () => {
    resolve();
    await transition.promise;
  });
  await viewTransition.updateCallbackDone;
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-Proposed In the Proposed Stage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants