Skip to content
Meeko
Type to search the guides and the API reference. Open it from any page with / or Ctrl K; move with the arrow keys and open a result with Enter.
Get started

Contents

On this page

defineGroup

Declares options in a +group.ts for an app/pages directory (named layout, its props and middleware) inherited by all its pages.

macro Since 1.5.0 No import @meekojs/meeko/framework Source code

Se autoimporta en las aplicaciones del framework.

ts
import { defineGroup } from "@meekojs/meeko/framework";

defineGroup declares an app/pages directory's options in its +group.ts file: the named layout, its props and, since 1.6, named middleware. All pages in the directory and its subdirectories inherit them, so you do not have to repeat layout or middleware in each definePage.

It is auto-imported. Meeko reads the file without executing it, like render: its values must be literals. This makes it work the same in SSR, prerendering and static sites.

Usage#

ts
// app/pages/(dashboard)/+group.ts
import { defineGroup } from "@meekojs/meeko/framework";

export default defineGroup({ layout: "dashboard", layoutProps: { showAlert: false }, middleware: ["auth"] });

All pages in app/pages/(dashboard)/ render inside app/layouts/dashboard.meeko with showAlert: false and first run the "auth" middleware.

Type#

ts
function defineGroup<const L extends LayoutName | false = string>(
  definition: GroupDefinition<L>,
): GroupDefinition<L>

GroupDefinition

ts
interface GroupDefinition<L extends LayoutName | false = LayoutName> {
	readonly layout?: L
	readonly layoutProps?: Partial<LayoutProps<L>>
	readonly middleware?: readonly RouteMiddlewareName[] | false
}

Options#

Option Type Default Description
layout layout name, or false outer group's layout, or default Named layout from app/layouts/<nombre>.meeko. false removes the named layout and keeps app/app.meeko and +layout.meeko files. Must be a literal.
layoutProps layout Props none Props for the layout, typed against the one selected by layout (or the inherited layout). A literal object of strings, numbers, booleans, null, arrays and objects. Merged by key with outer groups and the page, which takes precedence.
middleware names from app/middleware, or false inherited middleware Since 1.6. Named middleware added to those from outer groups without duplicates. false removes inherited middleware. Must be a literal array.

Return value#

The same definition, unchanged at runtime. What matters is the file: Meeko analyzes it when discovering routes and stores the result in each page's manifest.

Examples#

A private area with its own layout#

texto
app/layouts/dashboard.meeko
app/middleware/auth.server.ts          ← defineServerRouteMiddleware(…, { global: false })
app/pages/(dashboard)/+group.ts        ← defineGroup({ layout: "dashboard", middleware: ["auth"] })
app/pages/(dashboard)/reports.meeko
app/pages/(dashboard)/settings/index.meeko

/reports and /settings use dashboard and require a session. The (dashboard) directory is a group: it is not part of the URL.

Nested groups#

+group.ts files apply from the outside in, followed by the page:

ts
// app/pages/(dashboard)/admin/+group.ts
import { defineGroup } from "@meekojs/meeko/framework";

// Inherits layout "dashboard" and middleware ["auth"]; adds "admin" and changes a prop.
export default defineGroup({ layoutProps: { showAlert: true }, middleware: ["admin"] });

A page in admin/ runs auth and then admin, and its layout receives showAlert: true.

A page that opts out of the group#

The page takes precedence over its groups. With layout: false and middleware: false, it has neither the layout nor inherited middleware:

meeko
<!-- app/pages/(dashboard)/login.meeko -->
<script server lang="ts">
export const route = definePage({ layout: false, middleware: false });
</script>

<template><h1>Sign in</h1></template>

Common mistakes#

A layout that does not exist#

Incorrectts
export default defineGroup({ layout: "dashboard" });

Without app/layouts/dashboard.meeko, meeko check, meeko dev and meeko build stop with el layout "dashboard" no existe; crea app/layouts/dashboard.meeko (layouts disponibles: "default").

Correctts
// with app/layouts/dashboard.meeko
export default defineGroup({ layout: "dashboard" });

A computed value#

Meeko does not execute the file.

Incorrectts
const name = process.env.ADMIN ? "admin" : "default";
export default defineGroup({ layout: name });

layout debe ser un literal de texto (el nombre de un layout de app/layouts) o false para que Meeko pueda leerlo durante el build. The same applies to a spread or computed middleware.

Correctts
export default defineGroup({ layout: "admin" });

An option that does not exist#

Incorrectts
export default defineGroup({ layout: "default", sidebar: true });

opción de grupo desconocida "sidebar"; un +group.ts admite layout, layoutProps y middleware. Page options (render, load, head) belong in its definePage.

Correctts
export default defineGroup({ layout: "default", layoutProps: { sidebar: true } });

layoutProps not declared by the layout#

Incorrectts
export default defineGroup({ layout: "default", layoutProps: { title: "Dashboard" } });

If app/layouts/default.meeko does not declare title, meeko check reports TS2344: Type '"Las layoutProps de app/pages/(dash)/+group.ts no coinciden con las props del layout default"' does not satisfy the constraint 'true'.

Correctts
// app/layouts/default.meeko declares defineProps<{ title?: string }>()
export default defineGroup({ layout: "default", layoutProps: { title: "Dashboard" } });

A missing or global middleware#

Incorrectts
export default defineGroup({ middleware: ["auth", "locale"] });

el middleware "auth" no existe; crea app/middleware/auth.ts con defineRouteMiddleware(..., { global: false }) (middleware con nombre disponibles: ninguno), o app/middleware/auth.server.ts con defineServerRouteMiddleware para uno que sólo se ejecuta en el servidor. A global one, such as 10-locale.ts without options, reports el middleware "locale" (…) es global y ya se ejecuta en todas las rutas; quítalo de middleware o decláralo con defineRouteMiddleware(..., { global: false }).

Correctts
// with app/middleware/auth.server.ts declared with { global: false }
export default defineGroup({ middleware: ["auth"] });

Notes#

  • Placement. Only in +group.ts, in any directory under app/pages (a (nombre) group or an ordinary directory). A +group.ts outside app/pages configures nothing and meeko check warns with MEEK115.
  • Inheritance. layout is decided by the page or the innermost group that declares it. A group or page selecting another layout starts without inherited layoutProps, which belonged to the previous one.
  • Navigation. Pages sharing a layout keep it mounted when navigating between them, with its state and scroll position.
  • Security. Middleware requested by a group protects pages, not server/api or RPC: endpoints need their own guards. To check the session, use server middleware (*.server.ts).
  • Development. Creating, deleting or changing a +group.ts makes meeko dev rediscover routes.

Was this page helpful?

Add a comment

It is sent when you choose “Yes” or “No”. Only the page, your answer and the comment are stored: no cookies and no personal data.

0 of 2000 characters

Edit on GitHub: docs/en/reference/macros/definegroup.md