Skip to content

Instantly share code, notes, and snippets.

@bakatrouble
Last active August 8, 2025 12:29
Show Gist options
  • Save bakatrouble/55b1349df2e3e7abec1117ec8cb2e5c8 to your computer and use it in GitHub Desktop.
Save bakatrouble/55b1349df2e3e7abec1117ec8cb2e5c8 to your computer and use it in GitHub Desktop.
Use AdminJS with Nuxt/H3
// server/routes/admin/[...].ts
// server/routes/admin/index.ts
import { adminRouter } from '~~/server/admin/router';
export default useBase('/admin', adminRouter.handler);
// server/admin/router.ts
import { adminApp } from '~~/server/admin';
import { Router as AdminRouter } from "adminjs";
import { getRouterParams, type Router, sendStream } from 'h3';
import { readFiles } from 'h3-formidable';
import path from 'node:path';
import { createReadStream } from 'node:fs';
const checkAuthentication = (event: any) => {
return { email: 'abc' };
}
const buildRoute = ({ route, router }: {
route: (typeof AdminRouter)["routes"][number];
router: Router;
}) => {
router.add(
route.path.replace(/{/g, ":").replace(/}/g, ""),
eventHandler(async event => {
const auth = checkAuthentication(event);
if (!auth) {
throw createError({
statusCode: 401,
statusMessage: 'Unauthorized',
});
}
const controller = new route.Controller({ admin: adminApp }, auth);
const query = getQuery(event);
const params = getRouterParams(event);
const method = event.method.toLowerCase();
const { fields, files } = await readFiles(event);
const payload = {
...(fields || {}),
...(files || {}),
};
const html = await controller[route.action](
{
...event.node.req,
params,
query,
payload,
method,
},
event.node.res,
);
if (route.contentType) {
event.node.res.setHeader('Content-Type', route.contentType);
}
if (html) {
return html;
}
return null;
}),
route.method.toLowerCase() as 'get' | 'post',);
}
const buildRouter = () => {
const { routes, assets } = AdminRouter;
const router = createRouter();
const componentBundlerRoute = routes.find(
r => r.action === "bundleComponents"
);
if (componentBundlerRoute) {
buildRoute({ route: componentBundlerRoute, router });
}
assets.forEach((asset) => {
router.get(
asset.path,
eventHandler(event => {
let mimeType = undefined;
if (asset.path.endsWith('.js')) {
mimeType = 'application/javascript';
} else if (asset.path.endsWith('.css')) {
mimeType = 'text/css';
}
if (mimeType) {
event.node.res.setHeader('Content-Type', mimeType);
}
return sendStream(event, createReadStream(path.resolve(asset.src)))
})
);
});
routes.forEach(route => {
buildRoute({ route, router })
})
return router;
}
export const adminRouter = buildRouter();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment