_app.tsx Layout
Common site layout
views/_app.tsx is the site shell. It wraps every active view, so it is the right place for global providers, headers, footers, scroll restoration, tracking systems, and route-level UI.
import { Footer } from "@components/site/Footer"
import { Header } from "@components/site/Header"
import { ScrollRestoration } from "eddev/routing"
import { defineView } from "eddev/views"
export default defineView("_app", (props) => {
return (
<>
<ScrollRestoration />
<Header />
{props.children}
<Footer />
</>
)
})The children prop is the current route view. Do not query the current page in _app.tsx; that belongs in the view's own .graphql file.
App Data
Add views/_app.graphql for data needed across the whole frontend, such as menus, settings, trackers, or template parts.
query CommonData {
menus {
nodes {
locations
menuItems {
nodes {
label
url
parentId
}
}
}
}
templateParts {
siteFooter {
contentBlocks
}
}
}The result is available in _app.tsx as props, and also through useAppData() anywhere inside the app.
import { ContentBlocks } from "eddev/blocks"
import { useAppData } from "eddev/hooks"
export function Footer() {
const footer = useAppData((data) => data.templateParts?.siteFooter)
return <ContentBlocks blocks={footer?.contentBlocks} />
}On the initial page request, app data is included with the route payload. During normal client-side navigation it is reused, so avoid putting per-page data in _app.graphql.
Manual Route Display
Most projects only need {props.children}. More complex sites can render routes manually with RouteDisplay when they need page transitions, modal routes, drawers, or background routes.
import { Footer } from "@components/site/Footer"
import { Header } from "@components/site/Header"
import { RouteDisplay, useRoute } from "eddev/routing"
import { defineView } from "eddev/views"
export default defineView("_app", () => {
const route = useRoute()
return (
<>
<Header />
<RouteDisplay route={route} />
<Footer />
</>
)
})Only reach for this when the shell needs control over how the active route is displayed. For normal site layouts, keep _app.tsx boring.
App Data Versus View Data
- Use
_app.graphqlfor global data shared by many routes. - Use
views/name.graphqlfor data needed by one view. - Use
queries/*.graphqland generated hooks for interactive data that changes after the route has rendered.