Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
172 commits
Select commit Hold shift + click to select a range
f178dec
implement route serialization/deserialization
hajinsuha1 Mar 5, 2025
7b8b80b
initial pass at implementing route serialization via a componentMap
hajinsuha1 Mar 7, 2025
4f30443
update error handling message format
hajinsuha1 Mar 7, 2025
55c4415
cleanup and fix getRoutes to not duplicate routes
hajinsuha1 Mar 7, 2025
5da9d8e
Convert extendRoutes to an async method
vmarta Mar 8, 2025
4d13fe3
create a helper function generateComponentMapFromModules
hajinsuha1 Mar 10, 2025
8a54875
Add todos
vmarta Mar 10, 2025
4604d76
Temporarily modify the typescript-minimal project
vmarta Mar 10, 2025
e6542fc
initial impl of adding base template components to component map
hajinsuha1 Mar 10, 2025
7a1f51f
Minor refactoring
vmarta Mar 10, 2025
ddb88d2
Call every extension's route function in parallel
vmarta Mar 10, 2025
138f44b
create a prefixDisplayName utils
hajinsuha1 Mar 11, 2025
3bfa646
update error handling
hajinsuha1 Mar 11, 2025
2054078
fix deserialization of components from pwa-kit-react-sdk
hajinsuha1 Mar 11, 2025
a547b24
Merge branch 'vm/async-extendRoutes' into route-serialization-to-supp…
hajinsuha1 Mar 11, 2025
63a9d1f
merge
hajinsuha1 Mar 11, 2025
d90c79c
initial implementation of serialize/deserialize
hajinsuha1 Mar 12, 2025
c67fefa
cleanup
hajinsuha1 Mar 12, 2025
af9f3df
make serialize() and getComponentMap() synchronous
hajinsuha1 Mar 13, 2025
b002c86
Pass in the request path
vmarta Mar 13, 2025
bd74cf8
cache getRoutes using CacheResult decorator
hajinsuha1 Mar 14, 2025
b84c8c3
move deserialization logic to constructor of ApplicationExtension
hajinsuha1 Mar 14, 2025
3a9f90d
call this.getComponentMap within deserialize and fix typing
hajinsuha1 Mar 14, 2025
4a3a6ce
cleanup serialize logic
hajinsuha1 Mar 14, 2025
6d92af9
Explore passing in locals and how to manage access token
vmarta Mar 14, 2025
9f6c055
Remove extendRoutes from the API
vmarta Mar 15, 2025
6d5fb39
Allow configuring of the auth property name in locals
vmarta Mar 15, 2025
0115d21
comments + create DeserializedExtension type
hajinsuha1 Mar 17, 2025
fa85193
make getComponentMap abstract
hajinsuha1 Mar 17, 2025
040e3f1
add ComponentMap type to getComponentMap method in ChakraStorefront a…
hajinsuha1 Mar 17, 2025
86a78ed
add displayName to StoreLocatorPage
hajinsuha1 Mar 17, 2025
0a7e855
Rename the property in locals
vmarta Mar 17, 2025
9acff92
add unit tests for cacheResult
hajinsuha1 Mar 17, 2025
c5d924b
Create a new extension for a better example
vmarta Mar 17, 2025
2206dd5
Add some console logs
vmarta Mar 17, 2025
392387a
refactor Switch component to use RoutesProvider and create RoutesCons…
hajinsuha1 Mar 17, 2025
0c1bd41
update CacheResult decorator to support async methods and modify test…
hajinsuha1 Mar 17, 2025
08e72bd
enhance CacheResult decorator to support both async and sync methods …
hajinsuha1 Mar 18, 2025
0dbbb34
refactor getRoutes method to support both sync and async returns and …
hajinsuha1 Mar 18, 2025
8324897
refactor ApplicationExtension to enforce getComponentMap() for async …
hajinsuha1 Mar 18, 2025
5586726
cleanup ApplicationExtension and apply CacheResult to getRoutes metho…
hajinsuha1 Mar 18, 2025
645a91f
move CacheResult decorator logic to applyCacheForMethod in Applicatio…
hajinsuha1 Mar 18, 2025
d0ffc37
don't make getComponentMap abstract but make it optional
hajinsuha1 Mar 18, 2025
f97aaed
remove unused ComponentMap import from test files
hajinsuha1 Mar 18, 2025
42879f5
Experiment with having partial route
vmarta Mar 18, 2025
b71c0b9
Experiment with correct way to get app origin
vmarta Mar 18, 2025
bb692bc
Add todo
vmarta Mar 18, 2025
0d2ed3b
Some cleanup
vmarta Mar 18, 2025
35a453e
lint
hajinsuha1 Mar 19, 2025
272639f
cleanup
hajinsuha1 Mar 19, 2025
2067892
Fix the partial route with correct path
vmarta Mar 19, 2025
0e44b84
Remove no longer necessary code
vmarta Mar 19, 2025
1579626
Combine params into a single object
vmarta Mar 19, 2025
806fa87
Remove some console logs
vmarta Mar 19, 2025
85f9516
add async route handling and serialization tests for ApplicationExten…
hajinsuha1 Mar 19, 2025
11b5af3
Add comment to clarify
vmarta Mar 19, 2025
6402e62
handle all condiiton in deserialize and move applyCacheForMethod to a…
hajinsuha1 Mar 19, 2025
e8bba80
refactor: rename getRoutes to getRoutesAsync for clarity and update r…
hajinsuha1 Mar 19, 2025
af93217
refactor: remove isGetRoutesAsync method as it's no longer needed
hajinsuha1 Mar 19, 2025
579bdf3
Implement getRoutes and getRoutesAsync
vmarta Mar 20, 2025
18adf16
Add comment
vmarta Mar 20, 2025
d9b32e2
Add comment
vmarta Mar 20, 2025
4ad2535
Merge branch 'vm/async-extendRoutes' into route-serialization-to-supp…
hajinsuha1 Mar 20, 2025
965a34a
update getRoutesAsync to also return SerializedRoute and serialize to…
hajinsuha1 Mar 20, 2025
6baf649
cleanup decorator and chakra-storefront
hajinsuha1 Mar 20, 2025
5dbe489
update URLMapping.getRoutesAsync and BeforeRouteMatchParams to suppor…
hajinsuha1 Mar 20, 2025
26da1ee
address PR feedback
hajinsuha1 Mar 20, 2025
f1eab7c
update error message
hajinsuha1 Mar 20, 2025
0a1626c
fix cacheMethodResult
hajinsuha1 Mar 20, 2025
c622823
Add type to allow for `componentName` property
vmarta Mar 20, 2025
92a1c9a
fix ApplicationExtension.test.tsx
hajinsuha1 Mar 20, 2025
f615878
Merge branch 'vm/async-extendRoutes' into route-serialization-to-supp…
hajinsuha1 Mar 20, 2025
38e352f
Remove params for `getRoutes`
vmarta Mar 20, 2025
4119cda
Remove params for getRoutes
vmarta Mar 20, 2025
6677213
refactor: update route handling to use RouteProps exclusively and imp…
hajinsuha1 Mar 20, 2025
0058e80
Merge branch 'vm/async-extendRoutes' into route-serialization-to-supp…
hajinsuha1 Mar 20, 2025
fa4540a
refactor: rename GetRoutesParams to GetRoutesAsyncParams for to fix e…
hajinsuha1 Mar 20, 2025
4af8642
update unit tests
hajinsuha1 Mar 20, 2025
7fdd261
Revert "Remove params for `getRoutes`"
vmarta Mar 20, 2025
bcdcea3
Revert "Remove params for getRoutes"
vmarta Mar 20, 2025
7b48662
Merge branch 'vm/async-extendRoutes' into route-serialization-to-supp…
hajinsuha1 Mar 21, 2025
62e0060
reorganize imports for RoutesContext and unit tests
hajinsuha1 Mar 21, 2025
347c486
Merge branch 'route-serialization-to-support-shopper-seo-integration'…
hajinsuha1 Mar 21, 2025
de121c3
Add isServerSide utility function and corresponding tests
hajinsuha1 Mar 21, 2025
2152142
lint
hajinsuha1 Mar 21, 2025
ab23cd6
[REVERT] temporary logging for testing
hajinsuha1 Mar 21, 2025
5236d90
Remove unused properties from global Window interface in type definit…
hajinsuha1 Mar 21, 2025
131f670
update changelog
hajinsuha1 Mar 21, 2025
6e257cd
Refactor so that extension is the one in control of serialization
vmarta Mar 21, 2025
edcae1d
Update packages/pwa-kit-extension-sdk/src/react/classes/ApplicationEx…
hajinsuha1 Mar 24, 2025
04ee8fb
update unit tests and add error handling
hajinsuha1 Mar 24, 2025
c6be840
Merge branch 'route-serialization-to-support-shopper-seo-integration'…
hajinsuha1 Mar 24, 2025
c8e8035
lint
hajinsuha1 Mar 24, 2025
88419bf
lint
hajinsuha1 Mar 24, 2025
e9c00dd
lint extension-url-mapping
hajinsuha1 Mar 24, 2025
1de2122
Update comments
vmarta Mar 24, 2025
38425c2
Update tests
vmarta Mar 24, 2025
2bcbbc2
Update tests
vmarta Mar 24, 2025
7ba4d99
Revert changes to typescript-minimal
vmarta Mar 24, 2025
7c731f2
Merge branch 'feature/extensibility-v2' into vm/async-extendRoutes
vmarta Mar 24, 2025
a2096c3
Update package-lock.json
vmarta Mar 24, 2025
18a566f
Update changelog files
vmarta Mar 24, 2025
0e0edcb
Update readme files
vmarta Mar 24, 2025
422bd78
Merge branch 'vm/async-extendRoutes' into route-serialization-to-supp…
hajinsuha1 Mar 25, 2025
7ed9fbd
Refactor ApplicationExtension tests to use correct component types an…
hajinsuha1 Mar 25, 2025
e08d7ce
Remove extension-url-mapping package and associated files
hajinsuha1 Mar 25, 2025
bab7884
fix unit tests
hajinsuha1 Mar 25, 2025
c594557
Revert "Remove extension-url-mapping package and associated files"
hajinsuha1 Mar 25, 2025
794b0a3
lint
hajinsuha1 Mar 25, 2025
0cd67cc
Revert "Revert changes to typescript-minimal"
hajinsuha1 Mar 25, 2025
54ec28a
remove extension-url-mapping, logging, changes to typescript-minimal
hajinsuha1 Mar 25, 2025
6d7c6a9
update maxSize for build/vendor.js to 353 kB in template-retail-react…
hajinsuha1 Mar 25, 2025
12b071b
update CHANGELOG.md for template-retail-react-app
hajinsuha1 Mar 25, 2025
5f5de44
Add jsdoc to some types
vmarta Mar 25, 2025
ad8933a
Update packages/pwa-kit-extension-sdk/src/react/classes/ApplicationEx…
hajinsuha1 Mar 26, 2025
f65cf58
address PR feedback (remove unnecessary code)
hajinsuha1 Mar 26, 2025
876b4c2
Revert "remove extension-url-mapping, logging, changes to typescript-…
hajinsuha1 Mar 26, 2025
ad6d337
update ApplicationExtension unit test
hajinsuha1 Mar 26, 2025
f05a70a
Revert "Revert "remove extension-url-mapping, logging, changes to typ…
hajinsuha1 Mar 26, 2025
16f461b
Merge branch 'vm/async-extendRoutes' into route-serialization-to-supp…
hajinsuha1 Mar 26, 2025
052c99f
Merge branch 'feature/extensibility-v2' of https://github.com/Salesfo…
hajinsuha1 Mar 28, 2025
6d32d9d
don't allow returning partial routes from getRoutesAsync
hajinsuha1 Mar 28, 2025
6e3a71d
introduce SerializedRouteProps
hajinsuha1 Mar 28, 2025
8b17606
refactor serialize and deserialize to be more specific to routes (ser…
hajinsuha1 Apr 4, 2025
d1f42db
Merge branch 'feature/extensibility-v2' into route-serialization-to-s…
hajinsuha1 Apr 4, 2025
3cc8230
update changelog
hajinsuha1 Apr 4, 2025
23f3f26
Merge branch 'route-serialization-to-support-shopper-seo-integration'…
hajinsuha1 Apr 4, 2025
673728e
[App Extensibility ⚙️] Pin Specific Versions for Extensions in Genera…
adamraya Mar 31, 2025
d904807
Initial refactor of ssr into setup-server
bendvc Mar 27, 2025
ca31a1e
Refactor some of the utils and create middleware
bendvc Mar 28, 2025
4ef75d1
Remove wishlist from configurate list of pages for now
bendvc Mar 28, 2025
46ccd7b
Fix some lint errors
bendvc Mar 31, 2025
cc16ffc
Fix jwks path and replace constants with configurable values
bendvc Mar 31, 2025
a9a3bed
Empty commit
bendvc Mar 31, 2025
c658d3f
Fix regression and fix some tests config
bendvc Mar 31, 2025
572e689
Fix mock config
bendvc Mar 31, 2025
03dc975
Don't send undefined redirect urls
bendvc Apr 1, 2025
152aa8a
Use extension config not app config in checkout
bendvc Apr 1, 2025
6ed7d9f
Fix idps destructure
bendvc Apr 1, 2025
b5cd201
Fix test and pr feedback
bendvc Apr 1, 2025
d5d983e
Remove debugging logs
bendvc Apr 2, 2025
3c48a34
Removed unused error handler middleware
bendvc Apr 2, 2025
73d4793
Adding flex value as this component is used in display flex
bendvc Apr 2, 2025
14325a9
Better fix, still not great
bendvc Apr 2, 2025
d5e2de7
Fix issue with null pointer
bendvc Apr 2, 2025
caa865b
Lint
bendvc Apr 2, 2025
a45ea36
Update with-layout.tsx
bendvc Apr 2, 2025
9fbd8e7
Revert "remove extension-url-mapping, logging, changes to typescript-…
hajinsuha1 Apr 4, 2025
7dc6873
remove extension-url-mapping, logging, changes to typescript-minimal""
hajinsuha1 Apr 4, 2025
713d4e0
Revert "remove extension-url-mapping, logging, changes to typescript-…
hajinsuha1 Apr 4, 2025
fd025e6
Add displayName to Sample component and update component reference in…
hajinsuha1 Apr 4, 2025
5cf6e06
Commit for testing serialization
hajinsuha1 Apr 4, 2025
07e29dd
Merge branch 'route-serialization-to-support-shopper-seo-integration'…
hajinsuha1 Apr 4, 2025
533020b
fix package.json
hajinsuha1 Apr 4, 2025
840161e
Revert "Commit for testing serialization"
hajinsuha1 Apr 7, 2025
1504b0a
fix componentMap for testing in extension url mapping
hajinsuha1 Apr 7, 2025
26a60d6
Commit for testing serialization
hajinsuha1 Apr 7, 2025
b43928d
Merge branch 'feature/extensibility-v2' into route-serialization-to-s…
hajinsuha1 Apr 8, 2025
585669d
[App Extensibility] make sure DNT feature still works as expected (@W…
vmarta Apr 5, 2025
d0299fb
Add `build:watch` script, like what other packages have (#2346)
vmarta Apr 7, 2025
73f09f1
[App Extensibility] Bring back and fix the recently-skipped tests (@W…
vmarta Apr 8, 2025
66fc821
Initial commit
bendvc Apr 2, 2025
5bcec25
Lint
bendvc Apr 3, 2025
3d5febc
return empty routes when possible
hajinsuha1 Apr 10, 2025
a49f564
Merge branch 'route-serialization-to-support-shopper-seo-integration'…
hajinsuha1 Apr 10, 2025
a200b71
update unit tests
hajinsuha1 Apr 10, 2025
59c8eb7
Revert "Commit for testing serialization"
hajinsuha1 Apr 10, 2025
e6405b4
address PR feedback
hajinsuha1 Apr 11, 2025
02ef399
Revert "Revert "Commit for testing serialization""
hajinsuha1 Apr 11, 2025
80a9fb0
introduce NOT_CACHED symbol so that _cachedRoutes never has to be null
hajinsuha1 Apr 11, 2025
24b2195
fix unit tests
hajinsuha1 Apr 11, 2025
ba61551
add todo comment
hajinsuha1 Apr 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions packages/extension-chakra-storefront/src/setup-app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,15 @@ class ChakraStorefront extends ApplicationExtension<Config> {
ignoredRoutes: ['/callback']
})
}

async getComponentMap() {
const modules = await import('./pages')
const componentMap = Object.keys(modules).reduce((acc, key) => {
acc[modules[key].displayName] = modules[key]
return acc
}, {})
return componentMap
}
Copy link
Collaborator Author

@hajinsuha1 hajinsuha1 Mar 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was finding when I had this logic in ApplicationExtension.getComponentMap() it would error that it can't find ./pages.
Screenshot 2025-03-07 at 12 34 44 PM

Will continue to look for a solution that makes it so this function doesn't need to be implemented by every extension. Looking at making a protected method getComponentMapByPath that does the importing and have the default implementation call that method with the ./pages path to workaround this

}

export default ChakraStorefront
42 changes: 41 additions & 1 deletion packages/pwa-kit-react-sdk/src/ssr/browser/main.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {ServerContext, CorrelationIdProvider} from '../universal/contexts'
import App from '../universal/components/_app'
import {getAppConfig} from '../universal/compatibility'
import Switch from '../universal/components/switch'
import Refresh from '../universal/components/refresh'
import Throw404 from '../universal/components/throw-404'
import {getRoutes, routeComponent} from '../universal/components/route-component'
import {uuidv4} from '../../utils/uuidv4.client'
import logger from '../../utils/logger-instance'
Expand Down Expand Up @@ -132,10 +134,48 @@ export const start = async () => {
locals
})

// Create the component map
const PWA_KIT_REACT_SDK = "PWAKitReactSdk"
const componentMap = {
[PWA_KIT_REACT_SDK]: {
[Refresh.displayName]: Refresh,
[Throw404.displayName]: Throw404,
}
}
Copy link
Collaborator Author

@hajinsuha1 hajinsuha1 Mar 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

initialize the component map with the universal components added to routes in pwa-kit-react-sdk

for (const applicationExtension of applicationExtensions) {
const extensionName = applicationExtension.constructor.name
componentMap[extensionName] = await applicationExtension.getComponentMap()
}

// Deserialize routes
let serializedRoutes = window.__CONFIG__.app.routes
serializedRoutes = serializedRoutes.map(
({path, extensionId, componentName, componentProps}) => {
let component = componentMap[extensionId || PWA_KIT_REACT_SDK][componentName]
if (!component) {
// TODO: Error handling if given component couldn't be found
console.error(`Component "${componentName}" could not be deserialized for path: ${path}`)
return
}

if (componentProps) {
const Component = component
component = () => <Component {...componentProps} />
}
return {
path,
exact: true,
component
}
}
)
serializedRoutes = serializedRoutes.filter((route) => !!route)
routes = serializedRoutes

const props = {
error: window.__ERROR__,
locals: locals,
routes: getRoutes(locals),
routes: routes,
extensions: applicationExtensions,
WrappedApp
}
Expand Down
14 changes: 13 additions & 1 deletion packages/pwa-kit-react-sdk/src/ssr/server/react-rendering.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ export const render = async (req, res, next) => {
locals: res.locals
})

let routes = getRoutes(res.locals)
let routes = await getRoutes(res.locals, req)

const [pathname] = req.originalUrl.split('?')

Expand All @@ -150,6 +150,18 @@ export const render = async (req, res, next) => {
})
}

// Serialize the routes and add them to the config. We'll use this on the client-side later.
// TODO: we should not serialize the localized routes to reduce byte size
config.app.routes = routes.map((route) => {
Copy link
Collaborator Author

@hajinsuha1 hajinsuha1 Mar 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • consider only serializing one route from extendRoutes
  • move serialization logic to extension instead of base react-sdk
  • force customers to create a new extension to use an async extendRoutes that includes warnings to make sure the customer uses fast functions in the impl. This will prevent customers from creating slow functions with bad practices

const displayNameParts = route.component.displayName.match(/\(([^()]+)\)(?!.*\([^()]*\))/)[1].split('.')
return {
path: route.path,
extensionId: displayNameParts.length > 1 ? displayNameParts[0] : null,
componentName: displayNameParts.length > 1 ? displayNameParts[1]: displayNameParts[0],
componentProps: route.props
}
})

// Step 1 - Find the match.

// Call `beforeRouteMatch` application extension hook.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -402,17 +402,26 @@ export const routeComponent = (Wrapped, isPage, locals) => {
*
* @private
*/
export const getRoutes = (locals = {}) => {
export const getRoutes = async (locals = {}, req = {}) => {
let _routes = routes
const {applicationExtensions = []} = locals
if (typeof routes === 'function') {
_routes = routes()
_routes = await routes(locals)
}

// Call the `extendRoutes` function for all the Application Extensions.
applicationExtensions.forEach((applicationExtension) => {
_routes = applicationExtension.extendRoutes(_routes)
})
for (const applicationExtension of applicationExtensions) {
const routes = await applicationExtension.extendRoutes(_routes, req)
const extensionName = applicationExtension.constructor.name

// Prefix each component displayName with the extension name so it can later be deserialized
routes.forEach((route) => {
// Skip if component is already prefixed with an application extension name
if (route.component.displayName.includes(".") && route.component.displayName.match(/^[^.]+/)[0]) return
route.component.displayName = `${extensionName}.${route.component.displayName}`
})
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because extendRoutes modifies the original routes array, here I prefix the component displayName only when it doesn't have a prefix already. So any new routes added via an applicationExtension extendRoutes call will get the extension prefix added

_routes = routes
}

const allRoutes = [
// NOTE: this route needs to be above _routes, in case _routes has a fallback route of `path: '*'`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@
* SPDX-License-Identifier: BSD-3-Clause
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
import React from 'react'
import React, {useContext, useState} from 'react'
import PropTypes from 'prop-types'
import {Switch as RouterSwitch, Route} from 'react-router-dom'
import AppErrorBoundary from '../app-error-boundary'
import {UIDReset, UIDFork} from 'react-uid'

// TODO: can the context be moved to a HOC so routes don't always have to be serialized
const RoutesContext = React.createContext({})
export const useRoutesContext = () => useContext(RoutesContext)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I remember when I first did my spike I was being lazy when I placed this context and hook here. We will probably want to place them somewhere (possibly in their own file) where we can properly document their purpose.


/**
* The Switch component packages up the bits of rendering that are shared between
* server and client-side. It's *mostly* a react-router Switch component, hence the
Expand All @@ -21,24 +25,30 @@ import {UIDReset, UIDFork} from 'react-uid'
*/
const Switch = (props) => {
const {error, appState, routes, App} = props
const [_routes, setRoutes] = useState(routes)
return (
<UIDReset>
<AppErrorBoundary error={error}>
{!error && (
<App preloadedProps={appState.appProps}>
<RouterSwitch>
{routes.map((route, i) => {
const {component: Component, ...routeProps} = route
return (
<Route key={i} {...routeProps}>
<UIDFork>
<Component preloadedProps={appState.pageProps} />
</UIDFork>
</Route>
)
})}
</RouterSwitch>
</App>
<RoutesContext.Provider value={{
routes: _routes,
setRoutes
}}>
<App preloadedProps={appState.appProps}>
<RouterSwitch>
{_routes.map((route, i) => {
const {component: Component, ...routeProps} = route
return (
<Route key={i} {...routeProps}>
<UIDFork>
<Component preloadedProps={appState.pageProps} />
</UIDFork>
</Route>
)
})}
</RouterSwitch>
</App>
</RoutesContext.Provider>
)}
</AppErrorBoundary>
</UIDReset>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,6 @@ class Throw404 extends React.Component {
}
}

Throw404.displayName = 'Throw404'

export default Throw404
Loading