How to set menu in layout.tsx under folder as route parameter

views
├── customers
│   ├── {customersId}
│   │   ├───────────────other folder   
│   │   ├── @index.tsx
│   │   ├── edit.tsx
│   │   └── @layout.tsx (1)
│   └── @index.tsx
├── @index.tsx
└── @layout.tsx (2)

so Im trying add @layout.tsx under folder which name is route parameter
createMenuItems only give views with static path
but how can i get dynamic path views like customers/{customersId}/edit.tsx
so if customersId value is cake
then i expect get menu something like ‘cake/index.tsx’ 、 ‘cake/other folder’ 、 ‘cake/edit.tsx’ … auto without manually set views in layout.tsx

my tmp solution modify one from createMenuItems source code

import { type Signal, signal } from '@vaadin/hilla-react-signals';
import type { MenuItem, ViewConfig } from '@vaadin/hilla-file-router/types.js';

export enum RouteParamType {
  Required = 'req',
  Optional = 'opt',
  Wildcard = '*',
}

export type ServerViewConfig<T = unknown> = Readonly<{
  children?: readonly ServerViewConfig[];
  params?: Readonly<Record<string, RouteParamType>>;
}> &
  ViewConfig<T>;

export type  VaadinObject = Readonly<{
  views: Readonly<Record<string, ViewConfig>>;
}>;

export type  VaadinWindow = Readonly<{
  Vaadin?: VaadinObject;
}> &
  Window;

export const viewsSignal: Signal<Readonly<Record<string, Readonly<ViewConfig>>> | undefined> = signal(
  (window as unknown as VaadinWindow).Vaadin?.views,
);

function isExcluded(value: ViewConfig): boolean {
  return !!value.menu?.exclude;
}

function hasVariablePathSegment(path: string): boolean {
  return path.split('/').some((segment) => segment.startsWith(':customersId'));
}

export function createCustomersMenuItems<T = unknown>(): ReadonlyArray<MenuItem<T>> {
  const collator = new Intl.Collator('en-US');
  if (!viewsSignal.value) {
    return [];
  }

  const views = Object.entries(viewsSignal.value);

  return (
    views
      .filter(([path, value]) => !isExcluded(value) && hasVariablePathSegment(path))
      .map(([path, config]) => ({
        to: path,
        icon: config.menu?.icon,
        title: config.menu?.title ?? config.title,
        order: config.menu?.order,
        detail: config.detail as T | undefined,
      }))
      .sort((menuA, menuB) => {
        const ordersDiff = (menuA.order ?? Number.MAX_VALUE) - (menuB.order ?? Number.MAX_VALUE);
        return ordersDiff !== 0 ? ordersDiff : collator.compare(menuA.to, menuB.to);
      })
  );
}

and import to @layout.tsx

const { customersId } = useParams<{ customersId: string }>();
const items = createCustomersMenuItems().map((item) => ({
  ...item,
  to: (item.to ?? "").replace(":customersId", customersId?? ""),
}));

any better solution?
Thank you!

The implementation of createMenuItems utility intentionally leaves out the routes that aren’t directly accessible just by clicking on the auto generated menu items, as those with a parameter need something to set the parameter when being navigated to. In other words, it is optimizing for the generic use case. In your dynamic use case, I believe you need to implement your version of the createMenuItems as you’ve already done.