Skip to content

Commit

Permalink
Fix redirect loop in multistore mode - closes #3396
Browse files Browse the repository at this point in the history
  • Loading branch information
lukeromanowicz committed Aug 27, 2019
1 parent 201e470 commit 2a8c3db
Show file tree
Hide file tree
Showing 11 changed files with 23 additions and 34 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixed two bugs in `category-next/getCategoryFrom` (#3286) and `category-next/getCurrentCategory` (#3332) - @cewald (#3295)
- Fixed login popup close icon position - @przspa (#3393)
- Fixed styles for original price on Wishlist sidebar - @przspa (#3392)
- Redirect loop on dispatching dynamic routes in CSR running multistore mode - @cewald, @lukeromanowicz, @resubaka (#3396)

### Changed / Improved

Expand Down
6 changes: 4 additions & 2 deletions core/lib/router-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ const RouterManager = {
(registeredRoute) => registeredRoute.name === route.name && registeredRoute.path === route.path
) === -1
)
this._registeredRoutes.push(...uniqueRoutes)
router.addRoutes(uniqueRoutes)
if (uniqueRoutes.length > 0) {
this._registeredRoutes.push(...uniqueRoutes)
router.addRoutes(uniqueRoutes)
}
},
findByName: function (name: string): RouteConfig {
return this._registeredRoutes.find(r => r.name === name)
Expand Down
8 changes: 5 additions & 3 deletions core/modules/url/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,19 @@ export function parametrizeRouteData (routeData: LocalizedRoute, query: { [id: s
}

export function processDynamicRoute (routeData: LocalizedRoute, fullPath: string, addToRoutes: boolean = true): LocalizedRoute[] {
fullPath = removeStoreCodeFromRoute(fullPath) as string
const fullRootPath = removeStoreCodeFromRoute(fullPath) as string
const userRoute = RouterManager.findByName(routeData.name)

if (userRoute) {
if (addToRoutes) {
const routes = []
const rootDynamicRoute = Object.assign({}, userRoute, routeData, { path: '/' + fullPath, name: `urldispatcher-${fullPath}` })
const rootDynamicRoute = Object.assign({}, userRoute, routeData, { path: '/' + fullRootPath, name: `urldispatcher-${fullRootPath}` })
routes.push(rootDynamicRoute)
if (config.storeViews.mapStoreUrlsFor.length > 0 && config.storeViews.multistore === true) {
for (let storeCode of config.storeViews.mapStoreUrlsFor) {
if (storeCode) {
const dynamicRoute = Object.assign({}, userRoute, routeData, { path: '/' + ((config.defaultStoreCode !== storeCode) ? (storeCode + '/') : '') + fullPath, name: `urldispatcher-${fullPath}-${storeCode}` })
const multistorePath = '/' + ((config.defaultStoreCode !== storeCode && config.storeViews[storeCode].appendStoreCode) ? (storeCode + '/') : '') + fullRootPath
const dynamicRoute = Object.assign({}, userRoute, routeData, { path: multistorePath, name: `urldispatcher-${fullRootPath}-${storeCode}` })
routes.push(dynamicRoute)
}
}
Expand Down
16 changes: 10 additions & 6 deletions core/modules/url/router/beforeEach.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import { Logger } from '@vue-storefront/core/lib/logger'
import { processDynamicRoute, normalizeUrlPath } from '../helpers'
import { isServer } from '@vue-storefront/core/helpers'
import { storeCodeFromRoute, prepareStoreView, currentStoreView, LocalizedRoute } from '@vue-storefront/core/lib/multistore'
import Vue from 'vue'
import config from 'config'

export const UrlDispatchMapper = async (to) => {
const routeData = await store.dispatch('url/mapUrl', { url: to.fullPath, query: to.query })
return Object.assign({}, to, routeData)
}

export function beforeEachGuard (to: Route, from: Route, next) {
if (isServer) {
if (config.storeViews.multistore) { // this is called before server-entry.ts router.onReady - so we have to make sure we're in the right store context
Expand All @@ -28,15 +28,19 @@ export function beforeEachGuard (to: Route, from: Route, next) {
const hasRouteParams = to.hasOwnProperty('params') && Object.values(to.params).length > 0
const isPreviouslyDispatchedDynamicRoute = to.matched.length > 0 && to.name && to.name.startsWith('urldispatcher')

const lastRoute = store.getters['url/getLastMatchedRoute']
store.dispatch('url/registerLastMatchedRoute', to.name)

if (!to.matched.length || (!lastRoute.endsWith('page-not-found') && to.matched[0].name.endsWith('page-not-found')) || (isPreviouslyDispatchedDynamicRoute && !hasRouteParams)) {
if (!to.matched.length || to.matched[0].name.endsWith('page-not-found') || (isPreviouslyDispatchedDynamicRoute && !hasRouteParams)) {
UrlDispatchMapper(to).then((routeData) => {
if (routeData) {
let dynamicRoutes: LocalizedRoute[] = processDynamicRoute(routeData, fullPath, !isPreviouslyDispatchedDynamicRoute)

if (dynamicRoutes && dynamicRoutes.length > 0) {
const dynamicRouteByStore = config.storeViews.multistore ? dynamicRoutes.find(route => route.name.endsWith(currentStoreView().storeCode)) : false
let dynamicRouteByStore: boolean|LocalizedRoute = false

if (config.storeViews.multistore) {
const storeCode = storeCodeFromRoute(routeData.fullPath)
dynamicRouteByStore = dynamicRoutes.find(route => route.name.endsWith(storeCode))
}

next(dynamicRouteByStore || dynamicRoutes[0])
} else {
Logger.error('Route not found ' + routeData['name'], 'dispatcher')()
Expand Down
3 changes: 0 additions & 3 deletions core/modules/url/store/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,5 @@ export const actions: ActionTree<UrlState, any> = {
}
}
}
},
async registerLastMatchedRoute ({ commit }, routeName) {
commit(types.ADD_LAST_MATCHED_ROUTE, routeName)
}
}
9 changes: 0 additions & 9 deletions core/modules/url/store/getters.ts

This file was deleted.

4 changes: 1 addition & 3 deletions core/modules/url/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@ import { UrlState } from '../types/UrlState'
import { mutations } from './mutations'
import { actions } from './actions'
import { state } from './state'
import getters from './getters'

export const urlStore: Module<UrlState, any> = {
namespaced: true,
mutations,
actions,
state,
getters
state
}
1 change: 0 additions & 1 deletion core/modules/url/store/mutation-types.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export const REGISTER_MAPPING = 'URL/REGISTER_MAPPING'
export const ADD_LAST_MATCHED_ROUTE = 'URL/ADD_LAST_MATCHED_ROUTE'
3 changes: 0 additions & 3 deletions core/modules/url/store/mutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,5 @@ import * as types from './mutation-types'
export const mutations: MutationTree<any> = {
[types.REGISTER_MAPPING] (state, payload) {
state.dispatcherMap[payload.url] = payload.routeData
},
[types.ADD_LAST_MATCHED_ROUTE] (state, payload) {
state.lastMatchedRoute = payload
}
}
3 changes: 1 addition & 2 deletions core/modules/url/store/state.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { UrlState } from '../types/UrlState'

export const state: UrlState = {
dispatcherMap: {},
lastMatchedRoute: ''
dispatcherMap: {}
}
3 changes: 1 addition & 2 deletions core/modules/url/types/UrlState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,5 @@ import { LocalizedRoute } from 'core/lib/multistore'
// This object should represent structure of your modules Vuex state
// It's a good practice is to name this interface accordingly to the KET (for example mailchimpState)
export interface UrlState {
dispatcherMap: { [path: string]: LocalizedRoute},
lastMatchedRoute: string
dispatcherMap: { [path: string]: LocalizedRoute}
}

0 comments on commit 2a8c3db

Please sign in to comment.