Implementing Server-Side Menu Fetching in Ant Design Pro V5
Server-Side Menu Configuration in Ant Design Pro V5
To fetch menus from a server in Ant Design Pro V5, you can modify the runtime configuration in src/app.tsx using either the menu or menuDataRender options.
Configuration Options
- Using the
menuoption: This approach allows server-side menu fetching, but note that settinglocale: falsedoes not prevent menu names from being read from internationalization files. - Using the
menuDataRenderoption: This method respects thelocale: falsesetting, enabling menu names to bypass internationalization files.
Important: The following code only modifies the display of the left-side menu. The relationship between menu items and components must still be configured in config/routes.ts.
Example Implementation
export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) => {
return {
// Alternative menu configuration (commented out)
/*
menu: {
params: {
username: initialState?.currentUser?.user.userName,
},
request: async (params, defaultMenuData) => {
const menuData = initialState?.customMenuData;
const processedMenu = processMenuItems(menuData);
return [...defaultMenuData, ...(processedMenu || [])];
},
},
*/
rightContentRender: () => <RightContent />,
disableContentMargin: false,
waterMarkProps: {
content: initialState?.currentUser?.name,
},
footerRender: () => <Footer />,
onPageChange: () => {
const { location } = history;
if (!initialState?.currentUser && location.pathname !== loginPath) {
history.push(loginPath);
}
},
links: isDev
? [
<Link to="/umi/plugin/openapi" target="_blank">
<LinkOutlined />
<span>OpenAPI Documentation</span>
</Link>,
<Link to="/~docs">
<BookOutlined />
<span>Component Documentation</span>
</Link>,
]
: [],
// Server-side menu fetching using menuDataRender
menuDataRender: (menuItems) => {
const serverMenuData = initialState?.customMenuData || [];
const processedMenu = processMenuItems(serverMenuData);
return [...(processedMenu || [])];
},
menuHeaderRender: undefined,
menuItemRender: (menuItemProps, defaultDom) => {
if (menuItemProps.isUrl || !menuItemProps.path) {
return defaultDom;
}
return (
<Link to={menuItemProps.path}>
{menuItemProps.pro_layout_parentKeys &&
menuItemProps.pro_layout_parentKeys.length > 0 &&
menuItemProps.icon}
{defaultDom}
</Link>
);
},
childrenRender: (children, props) => {
return (
<>
{children}
{!props.location?.pathname?.includes('/login') && (
<SettingDrawer
enableDarkTheme
settings={initialState?.settings}
onSettingChange={(settings) => {
setInitialState((prevState) => ({
...prevState,
settings,
}));
}}
/>
)}
</>
);
},
...initialState?.settings,
};
};
Menu Item Processing Function
The processMenuItems functon handles icon assignment and component cleanup for menu items:
import { SYSTEM } from "@/services/system/typings";
import React from "react";
import * as allIcons from '@ant-design/icons';
export function processMenuItems(routes: SYSTEM.Router[]) {
return routes.map(item => {
if (item.iconName) {
const iconElement: React.ReactNode = React.createElement(allIcons[item.iconName]);
if (iconElement) {
item.icon = iconElement;
}
}
delete item.component;
if (item.routes && item.routes.length > 0) {
processMenuItems(item.routes);
}
return item;
});
}
Key Points
- Server Integration: The menu data is fetched from
initialState?.customMenuData, wich should be populated from your server API. - Icon Handling: Icons are dynamically created based on icon names from the server response.
- Component Management: The
componentproperty is removed from menu items since component relationships are managed separately inconfig/routes.ts. - Internationalization: Using
menuDataRenderwithlocale: falseprevents menu names from being overridden by internationalization files.
This implementation provides a flexible approach to server-side menu management while maintaining separation between menu structure and component routing.