-
Notifications
You must be signed in to change notification settings - Fork 146
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement dynamic update routes #2290
base: route-serialization-to-support-shopper-seo-integration
Are you sure you want to change the base?
Implement dynamic update routes #2290
Conversation
let {resourceTypeToComponentMap} = config | ||
console.log('config', config, 'resourceTypeToComponentMap', resourceTypeToComponentMap) | ||
if (resourceTypeToComponentMap === undefined) { | ||
resourceTypeToComponentMap = generateResourceTypeMap(allRoutes) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like callback functions are not supported values for the config/default.js
. Config fields with a callback function as the value get passed as undefined.
As a temporary workaround, I've copied the config code to a generateResourceTypeMap
util function in the sdk.
// TODO: How to call urlMapping API when React Hook "useUrlMapping" | ||
// cannot be called in a class component. React Hooks must be called | ||
// in a React function component or a custom React Hook function. | ||
const mapping = await getUrlMapping(path) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bendvc I think you briefly mentioned this but the useUrlMapping
hook from commerce-sdk-react
can't be called here because it needs to be used within a React hook or component.
For now instead of making an actual API call I made a mock function getUrlMapping
that returns the response for the following types of urlMappings: product
, category
, redirect
, content_asset
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please reach out the extensibility channel so we can start brain storming some idea's to solve this problem. I think this is potentially a blocker to getting this implemented.
// Await the async getRoutes function | ||
let routes = await getRoutes(locals) | ||
|
||
let serializedRoutes = window.__CONFIG__.app.routes | ||
// Deserialize routes | ||
serializedRoutes = serializedRoutes.map( | ||
({path, componentName, componentProps}) => { | ||
let component = routes.find((route) => | ||
route.component?.displayName?.includes(componentName) | ||
)?.component | ||
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bendvc Moved the deserialization to here so it only runs on client-side
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting.. would the async logic for making your seo url mapping called be called now on the client even though you have the routes serialized.
E.g. on line 135 you get the routes which will call the extendRoutes for all extensions and await on it.. then you will deserialize the routes starting at line 138. Effectively coming up with the same route list?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point it does seem unnecessary to deserialize routes that are already in the routes array.
I'll look to only serialize/deserialize the route of the current path
// TODO: support "content_asset" resource types | ||
Component = component | ||
props = { | ||
[`${urlMapping.resourceType}Id`]: urlMapping.resourceId | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bendvc still need to add support for mapping content_asset
resource types to a component
// DEVELOPER NOTE: Here we would want to use a Loadable component as to not bloat the home page chunk size. | ||
component: Component, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bendvc this note was here in the spike but do we still want to wrap this with a Loadable
component?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you planning on updating the README in this ticket or splitting it out into it's own?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking it'll be better to be on it's own so that we can write the README after we have all the changes for this extension implemented
type ResourceTypeToComponentMap = { | ||
category: string | ||
product: string | ||
content_asset: string | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might want to leverage the enum that the API uses or the response type and gave those values.. we know that the key might be an entry of the enum = CATEGORY | PRODUCT | CONTENT_ASSET which would hep clean up this type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We also still have the problem where we are mapping to the components display name. So we'll want to harden that solution a little. Maybe the pages in the storefront and store locator need to be prefixed with the extensions name/id to help prevent collisions or duplicate component/page names which might cause this solution to fall flat.
mapping.resourceType as keyof typeof resourceTypeToComponentMap | ||
] | ||
// TODO error handling if component not found | ||
const component = routes.find((route) => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One of the caveats of using extendRoutes
, and I know that I suggested that is the api method we use for this, is that "routes" is only a list of routes from the extensions that have been applied to the application before it.
Customers will have to know this via documentation (readme) that they have to add the seo mapping extension after all the extension, which might be weird. So lets put that in a decisions or findings section in your PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let go with the patter that each type has it's own file and the types file name and type name are synced. So we should call this serializedRoute.ts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
after I moved the serialization/deserialization to pwa-kit-react-sdk
this type is no longer in use so i've deleted it!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it will be wise to break out the reach sdk changes for serialization of the routes into it's own PR and then we can easily share that with more pwa-kit team members.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved to #2300
for (const applicationExtension of applicationExtensions) { | ||
_routes = await applicationExtension.extendRoutes(_routes, req) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will this code run the promises in parallel or one after another?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code will run one after another
… into implement-dynamic-update-routes
… into implement-dynamic-update-routes
Description
Types of Changes
Changes
extension-seo-url-mapping
extensionextendRoutes
method to make a Shopper SEOgetUrlMapping
API call and add it to the routes if a response is returnedpwa-kit-react-sdk
to serialize and deserialize routes to allow dynamically modifying the routes listHow to Test-Drive This PR
New Arrivals
category is renderedPlatinum Blue Stripes Easy Care Fitted Shirt
product is rendered/category/top-sellers
Checklists
General
Accessibility Compliance
You must check off all items in one of the follow two lists:
or...
Localization