📚 Build Menu from the folder based routing system in SvelteKit, NextJs, etc.
It will generate the menu on the fly and can also save it into a .json
file from which it can be loaded there on.
When starting building a new app and also later on it gives alot of ease to just get the menu on UI as soon as we add folders for the routes.
Many options are there to control the behavior of the Menu Generation and using it there after.
Pre-built Svelte components are also there ready to use in the view page files to render it. Working on to create NextJs components for it.
There will be separate packages for the components to reduce the package dependencies on this package.
@TODO: Post an Image sample of a generated menu.
@TODO: Put TOC here...
🟣 Installation
npm i @anupamtest/routes-menu
In SvelteKit
📒 Usage
By default SvelteKit routing files analogy is used.
Inside +layout.server.ts
first do the imports.
import { getMenu, type TMenuOptions } from '@anupamtest/routes-menu';
Simplest Example, No configuration, works for SvelteKit.
export const load = (async () => {
return {
menu: getMenu()
};
})
📒 Customized or Advanced Usage
although there's nothing critical in it ;)
⚙️ Using Menu Options
For other frameworks Set the routes folder path pattern to identify which folder to include in the Menu.
In the below example the routes path routesPath: 'src/routes/**/+page.svelte'
will include all those folders which contains the view page +page.svelte
in the Menu, which is the default analogy used in SvelteKit.
// In SvelteKit
export const load = (async () => {
const menuOptions: TMenuOptions = {
routesPath: 'src/routes/**/+page.svelte'
}
return {
menu: getMenu(menuOptions)
};
})
For NextJs framework we can set this path as below, depending upon the routing system we are using:
routesPath: 'src/pages/**/page.tsx'
OR
routesPath: 'app/**/page.tsx'
// In NextJs
const menuOptions: TMenuOptions = {
routesPath: 'app/**/page.tsx',
outputPath: 'app/',
outputFilename: 'menu.json'
}
const menu = getMenu(menuOptions)
const LayoutComponent = () => (
// return/store the menu data or render it here in some menu component...
<Menu menu={menu} />
)
Similarly it can be used with any other framework for Menu Generation.
⚙️ More Menu Options
⭕ Excluding Certain Routes
We definitely don't want to show certain folders from the routes in the Menu viz. auth
, admin
etc. depending upon our app.
You can very well exclude those via Menu Options.
const menuOptions: TMenuOptions = {
exclude: ['auth', 'admin/auth']
}
🟡 All the parameterized routes are excluded by default.
🔵 Will write some more examples for how we can use it...
⚙️ Below is the list of all the Menu Options
You can work very well with their combinations.
Putting this just for now...
Later will create a proper table to explain it and show more examples for its use cases in combination to each other, just like i used it.
export type TMenuOptions = {
/**
* The routes directory path pattern to match the directories to show in the menu.
* All parameterized directories are ignored. viz. /[userId]/
*
* @default 'src/routes/*\/**\/+page.svelte'
*
* @see https://www.npmjs.com/package/fast-glob for source path pattern
*/
routesPath?: string,
/**
* Whether to save the menu to a file from which it can be loaded further without generating it.
* When TRUE will save the menu every time it's generated from the routes directory filesystem.
*
* @default True
*/
saveToFile?: boolean,
/**
* Whether to load the menu from the saved menu file.
* Should keep this TRUE once the desired menu is generated and saved to a file.
*
* When FALSE will keep on generating the menu from the routes directory filesystem.
*
* @default true
*/
loadFromFile?: boolean,
/**
* The output path where to save the menu file.
* @RODO: Remove this and simply use `outputFilename`. `outputPath` hasn't used for any other purpose.
* @default 'src/lib/'
*/
outputPath?: string,
/**
* The output menu file name.
* @default 'menu.json'
*/
outputFilename?: string,
/**
* Backup the existing menu file before saving the new one, inside the set 'outputPath' directory.
*
* @default false
*/
backupExisting?: boolean,
/**
* May not need this! User ccan do this via css at their end
*/
// childMenuState?: 'open' | 'closed',
/**
* Show empty route directories also in the menu
* which do not have the index view file, viz. +page.svelte | page.tsx file.
*
* @default false
*/
showEmptyRoutes?: boolean,
/**
* The routes directories to exclude from the menu.
* @example
* These auth routes will not be shown in the menu.
* exclude: ['auth', 'admin/auth']
*/
exclude?: string[],
/**
* Menu Ordering, not yet implemented
* @TODO: Implement ordering...
*/
order?: unknown
}
📰 Generated Menu Sample
[
{
"name": "admin",
"label": "Admin",
"icon": "",
"url": "/admin",
"children": [
{
"name": "schemas",
"label": "Schemas",
"icon": "",
"url": "/admin/schemas",
"children": [
{
"name": "editor",
"label": "Editor",
"icon": "",
"url": "/admin/schemas/editor"
}
]
},
{
"name": "templates",
"label": "Templates",
"icon": "",
"url": "/admin/templates",
"children": [
{
"name": "editor",
"label": "Editor",
"icon": "",
"url": "/admin/templates/editor"
}
]
}
]
},
{
"name": "projects",
"label": "Projects",
"icon": "",
"url": "/projects",
"children": [
{
"name": "docs",
"label": "Docs",
"icon": "",
"url": "/projects/docs"
},
{
"name": "logs",
"label": "Logs",
"icon": "",
"url": "/projects/logs"
},
{
"name": "templates",
"label": "Templates",
"icon": "",
"url": "/projects/templates"
}
]
},
{
"name": "templates",
"label": "Templates",
"icon": "",
"url": "/templates"
}
]