diff --git a/packages/router/__tests__/guards/beforeEach.spec.ts b/packages/router/__tests__/guards/beforeEach.spec.ts index 4cc45e089..ddc15ef07 100644 --- a/packages/router/__tests__/guards/beforeEach.spec.ts +++ b/packages/router/__tests__/guards/beforeEach.spec.ts @@ -19,6 +19,10 @@ const routes: RouteRecordRaw[] = [ { path: 'home', name: 'nested-home', component: Home }, ], }, + { + path: '/redirect', + redirect: { path: '/other', state: { fromRecord: true } }, + }, ] describe('router.beforeEach', () => { @@ -106,6 +110,50 @@ describe('router.beforeEach', () => { expect(router.currentRoute.value.fullPath).toBe('/other') }) + it('can add state when redirecting', async () => { + const router = createRouter({ routes }) + await router.push('/foo') + router.beforeEach((to, from) => { + // only allow going to /other + if (to.fullPath !== '/other') { + return { + path: '/other', + state: { added: 'state' }, + } + } + return + }) + + const spy = jest.spyOn(history, 'pushState') + await router.push({ path: '/', state: { a: 'a' } }) + expect(spy).toHaveBeenCalledTimes(1) + // called before redirect + expect(spy).toHaveBeenNthCalledWith( + 1, + expect.objectContaining({ added: 'state', a: 'a' }), + '', + expect.stringMatching(/\/other$/) + ) + spy.mockClear() + }) + + it('can add state to a redirect route', async () => { + const router = createRouter({ routes }) + await router.push('/foo') + + const spy = jest.spyOn(history, 'pushState') + await router.push({ path: '/redirect', state: { a: 'a' } }) + expect(spy).toHaveBeenCalledTimes(1) + // called before redirect + expect(spy).toHaveBeenNthCalledWith( + 1, + expect.objectContaining({ fromRecord: true, a: 'a' }), + '', + expect.stringMatching(/\/other$/) + ) + spy.mockClear() + }) + async function assertRedirect(redirectFn: (i: string) => RouteLocationRaw) { const spy = jest.fn() const router = createRouter({ routes }) diff --git a/packages/router/src/router.ts b/packages/router/src/router.ts index e2d392cd9..40bf050b7 100644 --- a/packages/router/src/router.ts +++ b/packages/router/src/router.ts @@ -655,7 +655,10 @@ export function createRouter(options: RouterOptions): Router { if (shouldRedirect) return pushWithRedirect( assign(locationAsObject(shouldRedirect), { - state: data, + state: + typeof shouldRedirect === 'object' + ? assign({}, data, shouldRedirect.state) + : data, force, replace, }), @@ -735,7 +738,10 @@ export function createRouter(options: RouterOptions): Router { }, locationAsObject(failure.to), { - state: data, + state: + typeof failure.to === 'object' + ? assign({}, data, failure.to.state) + : data, force, } ),