View Data
Pipe WordPress data into your templates
A view can have a GraphQL file with the same name as the .tsx file. eddev executes that query whenever the view is resolved, and passes the query result to the view as props.
views/
page.tsx
page.graphql
single-case-study.tsx
single-case-study.graphqlYou do not call a hook or write a loading state for normal view data. If the query file exists, the data is part of the route payload before the view renders. If no query file exists, the view gets an empty props object.
Current Post Data
For views attached to a WordPress object, use $postId.
query Page($postId: ID!) {
page(id: $postId, idType: DATABASE_ID) {
title
contentBlocks
}
}import { ContentBlocks } from "eddev/blocks"
import { defineView } from "eddev/views"
export default defineView("page", (props) => {
return <ContentBlocks blocks={props.page?.contentBlocks} />
})$postId is usually available for page, front-page, single, single-{post-type}, and custom page templates. A $preview boolean is also sent when WordPress is rendering a preview.
Listing Data
View queries can fetch more than the current page. Archive and index pages often combine editable page content with a list of related posts or taxonomy terms.
query ArchiveCaseStudies($postId: ID!) {
page(id: $postId, idType: DATABASE_ID) {
contentBlocks
}
caseStudies(first: 100, where: { orderby: { field: MENU_ORDER, order: ASC } }) {
nodes {
title
uri
subtitle
}
}
workCategories {
nodes {
name
slug
}
}
}Use this pattern when authors need page-builder content at the top of an archive, but the view also needs structured data for filters, tiles, or navigation.
Custom Route Variables
Custom routes can provide their own query variables through ED()->addCustomRoute(). The PHP route maps URL segments to GraphQL variables, and the paired view query declares those variables.
ED()->addCustomRoute('planner/([A-Za-z0-9-]+)/?$', [
'template' => 'views/shared-planner.tsx',
'title' => 'Shared Planner',
'queryVars' => [
'plannerId' => "$1"
],
]);query SharedPlannerPage($plannerId: String!) {
sharedPlanner(id: $plannerId) {
id
name
sessions {
id
}
}
}Keep the route definition in Custom Routes, and keep this page focused on the view query that consumes the variables.
Generated Prop Types
eddev generates types.views.ts from views/**/*.tsx and views/**/*.graphql.
For a view with a query, the generated prop type comes from the GraphQL operation result. For a view without a query, the generated prop type is {}.
declare global {
interface ViewProps {
page: PageQuery
"shared-planner": SharedPlannerPageQuery
"search-results": {}
}
}Because defineView is typed against ViewProps, props should normally be inferred without manually importing the generated query type.
Query Scope
Use a view query for data needed before the route renders. Use a query hook in queries/*.graphql when the user needs to search, paginate, mutate, refetch, or otherwise load data dynamically after the view is already on screen.