From f749d8dc0c73fb76b20008435b5efcfa6a3c4c30 Mon Sep 17 00:00:00 2001 From: Joe Fusco Date: Fri, 16 Oct 2026 17:16:57 -0400 Subject: [PATCH 1/5] docs: explain using multiple queries in a template --- .../index.md | 152 ++++++++++++++++++ docs/nav.json | 4 + 2 files changed, 156 insertions(+) create mode 100644 docs/how-to/use-multiple-queries-in-a-template/index.md diff --git a/docs/how-to/use-multiple-queries-in-a-template/index.md b/docs/how-to/use-multiple-queries-in-a-template/index.md new file mode 100644 index 000000000..d39ffdf19 --- /dev/null +++ b/docs/how-to/use-multiple-queries-in-a-template/index.md @@ -0,0 +1,152 @@ +--- +title: "Use Multiple Queries in a Template" +description: "Guide to splitting a Faust.js template's data into several GraphQL queries with Component.queries and reading each result with useFaustQuery." +--- + +A template can run several GraphQL queries instead of one. This lets you reuse a query across templates, such as a layout query for the site title and menus, and keep a separate query for the content of the post, page or archive being rendered. + +Define the queries in a static `Component.queries` array, then read each result with the `useFaustQuery` hook. + +## 0. Prerequisites + +If you haven't already, follow the [Basic Setup](/docs/how-to/basic-setup/) steps to get Faust.js set up, and make sure your app renders templates from `wp-templates` through [`getWordPressProps`](/docs/reference/get-wordpress-props/) and `WordPressTemplate`. + +## 1. Create a reusable query + +Put the query you want to share in its own file so every template can import it. This layout query fetches the site's general settings and two menus: + +```js title="fragments/LayoutQuery.js" +import { gql } from "@apollo/client"; + +export const GET_LAYOUT_QUERY = gql` + query GetLayout( + $headerLocation: MenuLocationEnum + $footerLocation: MenuLocationEnum + ) { + generalSettings { + title + description + } + headerMenuItems: menuItems(where: { location: $headerLocation }) { + nodes { + id + uri + label + } + } + footerMenuItems: menuItems(where: { location: $footerLocation }) { + nodes { + id + uri + label + } + } + } +`; +``` + +## 2. Add the queries to the template + +In the template, list each query in `Component.queries`. Each entry has a `query` and an optional `variables` function: + +```js title="wp-templates/single.js" +import { gql } from "@apollo/client"; +import { GET_LAYOUT_QUERY } from "../fragments/LayoutQuery"; + +const GET_POST_QUERY = gql` + query GetPost($databaseId: ID!, $asPreview: Boolean = false) { + post(id: $databaseId, idType: DATABASE_ID, asPreview: $asPreview) { + title + content + } + } +`; + +export default function Component(props) { + // We'll fill this in next. +} + +Component.queries = [ + { + query: GET_LAYOUT_QUERY, + variables: () => ({ + headerLocation: "PRIMARY", + footerLocation: "FOOTER", + }), + }, + { + query: GET_POST_QUERY, + variables: ({ databaseId }, ctx) => ({ + databaseId, + asPreview: ctx?.asPreview, + }), + }, +]; +``` + +Each `variables` function receives the same arguments as `Component.variables`: the [seed node](/docs/explanation/seed-query/), a context object with `asPreview` and `locale`, and any [`extra` arguments](/docs/reference/get-wordpress-props/#passing-extra-arguments) passed to `getWordPressProps`. + +Faust runs all of the queries at the same time and stores each result for the template to read. + +## 3. Read the results with `useFaustQuery` + +Call `useFaustQuery` with the same query you listed in `Component.queries` to get its data: + +```js title="wp-templates/single.js" +import { gql } from "@apollo/client"; +import { useFaustQuery } from "@faustwp/core"; +import { GET_LAYOUT_QUERY } from "../fragments/LayoutQuery"; + +// GET_POST_QUERY from step 2 + +export default function Component(props) { + const { post } = useFaustQuery(GET_POST_QUERY) ?? {}; + const { generalSettings, headerMenuItems, footerMenuItems } = + useFaustQuery(GET_LAYOUT_QUERY) ?? {}; + + // Loading state for previews + if (props.loading) { + return <>Loading...; + } + + return ( + <> +
+

{generalSettings?.title}

+ +
+
+

{post?.title}

+
+
+ + + ); +} + +// Component.queries from step 2 +``` + +`useFaustQuery` returns `undefined` until the query has data, for example while a preview loads in the browser, so fall back to an empty object as shown above. Call it before any early return, since it's a React hook. + +> [!note] Learn More +> The [getting started example](https://github.com/wpengine/faustjs/tree/canary/examples/next/faustwp-getting-started/wp-templates) uses `Component.queries` with a shared layout query in each of its templates. + +## How `Component.queries` differs from `Component.query` + +- **Use one or the other.** A template can define `Component.query` or `Component.queries`, not both. Faust throws `Only either Component.query or Component.queries can be provided, but not both.` if it finds both. +- **Results come from `useFaustQuery`, not `props.data`.** `props.data` is only filled in for `Component.query`. +- **Queries run again in the browser.** After the page loads, Faust runs the queries again in the browser, and on previews it only runs them there. In the browser, the `variables` functions receive the seed node and `asPreview`, but not `locale` or `extra`. +- **Each query can only be listed once.** Faust stores results by the query's text, so listing the same query twice with different variables keeps only the last result. To fetch the same data with different variables, define a second query with a different operation name. See [#1742](https://github.com/wpengine/faustjs/issues/1742). diff --git a/docs/nav.json b/docs/nav.json index d997ce3ab..b52fa5c31 100644 --- a/docs/nav.json +++ b/docs/nav.json @@ -59,6 +59,10 @@ "title": "Query Data in Next.js Routes", "route": "/docs/how-to/query-data-in-nextjs-routes/" }, + { + "title": "Use Multiple Queries in a Template", + "route": "/docs/how-to/use-multiple-queries-in-a-template/" + }, { "title": "Write Data to WordPress", "route": "/docs/how-to/write-data-to-wordpress/" From 3d98bc2915d225e93286990b2af257ab1463e21d Mon Sep 17 00:00:00 2001 From: Joe Fusco Date: Fri, 16 Oct 2026 17:17:25 -0400 Subject: [PATCH 2/5] docs: match the exact error text and note the FaustProvider requirement --- docs/how-to/use-multiple-queries-in-a-template/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/how-to/use-multiple-queries-in-a-template/index.md b/docs/how-to/use-multiple-queries-in-a-template/index.md index d39ffdf19..3d762d56e 100644 --- a/docs/how-to/use-multiple-queries-in-a-template/index.md +++ b/docs/how-to/use-multiple-queries-in-a-template/index.md @@ -139,14 +139,14 @@ export default function Component(props) { // Component.queries from step 2 ``` -`useFaustQuery` returns `undefined` until the query has data, for example while a preview loads in the browser, so fall back to an empty object as shown above. Call it before any early return, since it's a React hook. +`useFaustQuery` returns `undefined` until the query has data, for example while a preview loads in the browser, so fall back to an empty object as shown above. Call it before any early return, since it's a React hook. It reads from `FaustProvider`, so it throws if your app isn't wrapped in `FaustProvider` as shown in [Basic Setup](/docs/how-to/basic-setup/). > [!note] Learn More > The [getting started example](https://github.com/wpengine/faustjs/tree/canary/examples/next/faustwp-getting-started/wp-templates) uses `Component.queries` with a shared layout query in each of its templates. ## How `Component.queries` differs from `Component.query` -- **Use one or the other.** A template can define `Component.query` or `Component.queries`, not both. Faust throws `Only either Component.query or Component.queries can be provided, but not both.` if it finds both. +- **Use one or the other.** A template can define `Component.query` or `Component.queries`, not both. Faust throws ``Only either `Component.query` or `Component.queries` can be provided, but not both.`` if it finds both. - **Results come from `useFaustQuery`, not `props.data`.** `props.data` is only filled in for `Component.query`. - **Queries run again in the browser.** After the page loads, Faust runs the queries again in the browser, and on previews it only runs them there. In the browser, the `variables` functions receive the seed node and `asPreview`, but not `locale` or `extra`. - **Each query can only be listed once.** Faust stores results by the query's text, so listing the same query twice with different variables keeps only the last result. To fetch the same data with different variables, define a second query with a different operation name. See [#1742](https://github.com/wpengine/faustjs/issues/1742). From f57d94fa438f688e24b4010d2265c994c63cfe32 Mon Sep 17 00:00:00 2001 From: Joe Fusco Date: Fri, 16 Oct 2026 17:17:36 -0400 Subject: [PATCH 3/5] docs: retitle the limitations section and tidy the browser re-run note --- docs/how-to/use-multiple-queries-in-a-template/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/how-to/use-multiple-queries-in-a-template/index.md b/docs/how-to/use-multiple-queries-in-a-template/index.md index 3d762d56e..514efc992 100644 --- a/docs/how-to/use-multiple-queries-in-a-template/index.md +++ b/docs/how-to/use-multiple-queries-in-a-template/index.md @@ -144,9 +144,9 @@ export default function Component(props) { > [!note] Learn More > The [getting started example](https://github.com/wpengine/faustjs/tree/canary/examples/next/faustwp-getting-started/wp-templates) uses `Component.queries` with a shared layout query in each of its templates. -## How `Component.queries` differs from `Component.query` +## Notes and limitations - **Use one or the other.** A template can define `Component.query` or `Component.queries`, not both. Faust throws ``Only either `Component.query` or `Component.queries` can be provided, but not both.`` if it finds both. - **Results come from `useFaustQuery`, not `props.data`.** `props.data` is only filled in for `Component.query`. -- **Queries run again in the browser.** After the page loads, Faust runs the queries again in the browser, and on previews it only runs them there. In the browser, the `variables` functions receive the seed node and `asPreview`, but not `locale` or `extra`. +- **Queries run again in the browser.** After the page loads, Faust runs the queries again in the browser. On previews, they only run in the browser. In the browser, the `variables` functions receive the seed node and `asPreview`, but not `locale` or `extra`. - **Each query can only be listed once.** Faust stores results by the query's text, so listing the same query twice with different variables keeps only the last result. To fetch the same data with different variables, define a second query with a different operation name. See [#1742](https://github.com/wpengine/faustjs/issues/1742). From 7b041d248915e839d3d0b609ee75194d43a4d916 Mon Sep 17 00:00:00 2001 From: Joe Fusco Date: Fri, 16 Oct 2026 17:18:11 -0400 Subject: [PATCH 4/5] docs: link the getWordPressProps extra arguments to Component.queries --- docs/reference/get-wordpress-props/index.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/reference/get-wordpress-props/index.md b/docs/reference/get-wordpress-props/index.md index 1ea09f9b8..97d94775c 100644 --- a/docs/reference/get-wordpress-props/index.md +++ b/docs/reference/get-wordpress-props/index.md @@ -76,3 +76,5 @@ Component.variables = ({ databaseId }, ctx, extra) => { ... } ``` + +The `variables` function of each query in [`Component.queries`](/docs/how-to/use-multiple-queries-in-a-template/) receives `extra` the same way when the queries run on the server. From 69e4acc3ff7b0b2c1e2837c460d1c76e071456de Mon Sep 17 00:00:00 2001 From: Joe Fusco Date: Fri, 16 Oct 2026 17:48:27 -0400 Subject: [PATCH 5/5] docs: note that variables get locale and extra only on the server --- docs/how-to/use-multiple-queries-in-a-template/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/how-to/use-multiple-queries-in-a-template/index.md b/docs/how-to/use-multiple-queries-in-a-template/index.md index 514efc992..2726419c0 100644 --- a/docs/how-to/use-multiple-queries-in-a-template/index.md +++ b/docs/how-to/use-multiple-queries-in-a-template/index.md @@ -84,7 +84,7 @@ Component.queries = [ ]; ``` -Each `variables` function receives the same arguments as `Component.variables`: the [seed node](/docs/explanation/seed-query/), a context object with `asPreview` and `locale`, and any [`extra` arguments](/docs/reference/get-wordpress-props/#passing-extra-arguments) passed to `getWordPressProps`. +When the queries run on the server, each `variables` function receives the same arguments as `Component.variables`: the [seed node](/docs/explanation/seed-query/), a context object with `asPreview` and `locale`, and any [`extra` arguments](/docs/reference/get-wordpress-props/#passing-extra-arguments) passed to `getWordPressProps`. Faust runs all of the queries at the same time and stores each result for the template to read.