Hi @mburridge,
Apologies for not getting back sooner. I was determined to get this working and I finally got everything did! I couldnāt share a repo because itās a private company project. Tbh me figuring it out was more a result of just diving into the code more to understand what was really happening.
A few things did help me though, Iāve listed them below in case others read this:
I used this plugin to expose the menus:
This plugin exposes the following routes and itās important to be mindful of these paths.
-
/menus/v1/menus
list of every registered menu.
-
/menus/v1/menus/<slug>
data for a specific menu.
-
/menus/v1/locations
list of every registered menu location in your theme.
-
/menus/v1/locations/<slug>
data for a specific menu location.
Handler Code
In my handler when I was fetching the data from the source:
const response = await libraries.source.api.get({
endpoint: `/menus/v1/menus/${slug}`
});
I initially had the endpoint starting without a /
. I later read on another post the following:
If the "endpoint"
value doesnāt start with "/"
, it will add "/wp/v2"
first. So when my endpoint should have been:
https://ripple-web.lndo.site/wp-json/menus/v1/menus/footer-about-us
it was actually:
https://ripple-web.lndo.site/wp-json/wp/v2/menus/v1/menus/footer-about-us
Which was incorrect.
Handler Code and beforeSSR action
Lastly I think I had the path / route in my actions.source.fetch
call incorrect in the theme actions. Here is my handler code and my beforeSSR call in my marsTheme config that works.
> actions: {
> theme: {
> // special Frontity action fired to prepare the state for the React render made in the server
> beforeSSR: async ({actions}) => {
> await actions.source.fetch('menus/footer-menu') // /menus/v1/menus/<slug> data for a specific menu location.
> },
> toggleMobileMenu: ({ state }) => {
> state.theme.isMobileMenuOpen = !state.theme.isMobileMenuOpen;
> },
> closeMobileMenu: ({ state }) => {
> state.theme.isMobileMenuOpen = false;
> },
> },
> },
// handler
export const footerMenuHandler = {
name: "footerMenu",
priority: 10,
pattern: "menus/:slug",
func: async ({ route, params, state, libraries, force }) => {
console.log(params.slug);
console.log("Route: " + route);
const { slug } = params;
console.log("Slug: " + slug);
// 1. fetch the data you want from the endpoint page
const response = await libraries.source.api.get({
endpoint: `/menus/v1/menus/${slug}`
});
// this is where we get the actual data
// 2. get our menu object in json format
const menu = await response.json();
console.log(menu);
// this is a reference to the state object for this link currently, get this and it wil be the target object which
// we assign our data from items to in object.assign
// 3. add data to source
const currentPageData = state.source.data[route];
Object.assign(currentPageData, {
slug,
items: menu.items, // @ni.bonev figured this one out because the "items" property contains an array of items
isMenu: true
});
}
};
I believe the pattern
in the handler and the route in my actions.source.fetch
need to coordinate or match if you will. The menu Iām fetching is a menu created in WordPress however I had to register it in php with the register_nav_menu WordPress function in order to register it with the slug I wanted, in this case footer-menu
php code to register the menu with the slug I wanted. Though I donāt think I had to do this . . .
//add footer menu
function register_footer_menu() {
register_nav_menu('footer-menu',__( 'Footer Menu'));
}
add_action( 'init', 'register_footer_menu');
Anyway long and short of it is that now itās working like a charm and Iāve built my sites footer Thanks again!