Q-Press Navigation

Q-Press navigation is driven by src/siteConfig/index.ts. Header and footer menus usually use direct route paths, while sidebar menus often use slugified grouping nodes.

Route Paths

For each Markdown file in src/markdown, Vue Router generates a matching route:

src/markdown/getting-started/introduction.md
  -> /getting-started/introduction

src/markdown/quasar-app-extensions/qpress/site-config.md
  -> /quasar-app-extensions/qpress/site-config

If the folder name and file name are the same, Q-Press removes the duplicate segment:

src/markdown/vite-plugins/vite-md-plugin/vite-md-plugin.md
  -> /vite-plugins/vite-md-plugin

Use these route paths in header links, sidebar children, related links, and card links.

The landing page is the source-file exception. Link to it as /, even though the file is named src/markdown/landing-page.md. See Customizing The Landing Page for the page-specific setup.

RegionConfigure withBest for
Headerlinks.primaryHeaderLinks, links.secondaryHeaderLinksHigh-priority sections and short route groups.
More menulinks.moreLinksHeader items that should collapse at smaller widths.
SidebarsidebarFull documentation outline and nested sections.
Footerlinks.footerLinks, links.socialLinks, license, privacy, copyrightSponsor links, external references, legal links, and social links.

Create top-level menu groups in src/siteConfig/index.ts:

const 
const mdPluginsMenu: {
    name: string;
    mq: number;
    children: {
        name: string;
        children: {
            name: string;
            path: string;
        }[];
    }[];
}
mdPluginsMenu
= {
name: stringname: 'MD Plugins', mq: numbermq: 600,
children: {
    name: string;
    children: {
        name: string;
        path: string;
    }[];
}[]
children
: [
{ name: stringname: 'Blockquote',
children: {
    name: string;
    path: string;
}[]
children
: [
{ name: stringname: 'Overview', path: stringpath: '/md-plugins/blockquote/overview' }, { name: stringname: 'Advanced', path: stringpath: '/md-plugins/blockquote/advanced' }, ], }, { name: stringname: 'Codeblocks',
children: {
    name: string;
    path: string;
}[]
children
: [
{ name: stringname: 'Overview', path: stringpath: '/md-plugins/codeblocks/overview' }, { name: stringname: 'Advanced', path: stringpath: '/md-plugins/codeblocks/advanced' }, ], }, ], }

Use mq to decide when a menu should move into the More menu. Match those breakpoints to the values in your Q-Press theme variables. See Themes.

interface MenuItem {
  MenuItem.name: stringname: string
  MenuItem.path?: string | undefinedpath?: string
  MenuItem.icon?: string | undefinedicon?: string
  MenuItem.iconColor?: string | undefinediconColor?: string
  MenuItem.rightIcon?: string | undefinedrightIcon?: string
  MenuItem.rightIconColor?: string | undefinedrightIconColor?: string
  MenuItem.badge?: string | undefinedbadge?: string
  MenuItem.children?: MenuItem[] | undefinedchildren?: MenuItem[] | undefined
  MenuItem.external?: boolean | undefinedexternal?: boolean
  MenuItem.expanded?: boolean | undefinedexpanded?: boolean
}
PropertyUse it for
nameVisible label for the link or group.
pathInternal route path, external URL, or '' for a visual-only sidebar group.
icon, iconColor, rightIcon, rightIconColorHeader, sidebar, footer, or card-style link decoration.
badgeSmall status label beside a menu item.
childrenNested menu groups.
externalOpens links with external-link behavior.
expandedInitial expansion state for sidebar groups.
mqResponsive breakpoint used to show or hide header items.
image, maxWidthImage-style footer or sponsor links.

Sidebar menu items represent drawer sections instead of flat header links. Use the sidebar export in Site Config to control drawer navigation.

When a header menu already has the structure you want, process it into a sidebar-safe tree:

function getSidebarPath(item: MenuItem): string {
  if (item.path === '') {
    return ''
  }

  const path = item.path?.replace(/^\/+/, '').split('/').filter(Boolean).pop()
  return path ?? slugify(item.name)
}

function processMenuItem(item: MenuItem): MenuItem {
  return {
    name: item.name,
    path: getSidebarPath(item),
    expanded: item.expanded ?? false,
    children: item.children ? item.children.map(processMenuItem) : undefined,
  }
}

Then add the processed menu to sidebar:

export const sidebar = [
  processedMdPluginsMenu,
  processedVitePluginsMenu,
  processedQuasarAppExts,
  processedOtherMenu,
]

Use path: '' when a sidebar item is only a visual grouping node and should not contribute a URL segment. This keeps grouped children under their real route instead of creating a route such as /examples/agenda/recipes/planner.

const examplesMenu = {
  name: 'Examples',
  path: '/examples',
  children: [
    {
      name: 'Agenda',
      path: '/examples/agenda',
      children: [
        {
          name: 'Recipes',
          path: '',
          children: [{ name: 'Planner', path: '/examples/agenda/planner' }],
        },
      ],
    },
  ],
} satisfies MenuItem

Reserve path: '' for sidebar-only grouping nodes. Real pages and header links should keep explicit route paths.

The moreLinks array controls the responsive overflow menu. Items are displayed based on media query breakpoints and are removed from the normal header menu when they no longer fit.

const 
const guidesMenu: {
    name: string;
    mq: number;
    children: {
        name: string;
        path: string;
    }[];
}
guidesMenu
= {
name: stringname: 'Guides', mq: numbermq: 780,
children: {
    name: string;
    path: string;
}[]
children
: [
{ name: stringname: 'Installation', path: stringpath: '/getting-started/installation' }, { name: stringname: 'Themes', path: stringpath: '/quasar-app-extensions/qpress/themes' }, ], } const
const links: {
    secondaryHeaderLinks: {
        name: string;
        mq: number;
        children: {
            name: string;
            path: string;
        }[];
    }[];
    moreLinks: {
        name: string;
        mq: number;
        children: {
            name: string;
            path: string;
        }[];
    }[];
}
links
= {
secondaryHeaderLinks: {
    name: string;
    mq: number;
    children: {
        name: string;
        path: string;
    }[];
}[]
secondaryHeaderLinks
: [
const guidesMenu: {
    name: string;
    mq: number;
    children: {
        name: string;
        path: string;
    }[];
}
guidesMenu
],
moreLinks: {
    name: string;
    mq: number;
    children: {
        name: string;
        path: string;
    }[];
}[]
moreLinks
: [
const guidesMenu: {
    name: string;
    mq: number;
    children: {
        name: string;
        path: string;
    }[];
}
guidesMenu
],
}