In this post we explore how You can extend the GraphQL schema in the WordPress backend and sync the new data with the frontend.
Adding schema to WPGraphQL with PHP
So basically You can register any type of WordPress data with native WPGraphQL PHP functions as described here. This requires functions.php
modifications or writing you custom WP plugin. Here is a small example:
// additional GRAPHQL DATA
// Add the new types to wp-graphql-woocommerce
// EUR + language code for products
add_action('graphql_register_types', function () {
global $post;
register_graphql_field('Product', 'translationsUrls', [
'type' => ['list_of' => 'String'],
'resolve' => function (\WPGraphQL\WooCommerce\Model\Product $product, $args, $context, $info) {
$product_language = pll_get_post_language($product->ID);
// Get the product translation metadata
$product_translation_url_metadata = pll_get_post_translations($product->ID, $product_language);
// Create a new array
$trans_array = [];
// Loop through the product IDs and get the product URLs
foreach ($product_translation_url_metadata as $language => $product->ID) {
// Get the product URL
$product_url = get_permalink($product->ID);
// Remove the site URL from the product permalink
$relative_permalink = str_replace(get_site_url(), '', $product_url);
// Return the relative product permalink
$trans_array[] = $relative_permalink;
}
return $trans_array;
}
]);
register_graphql_fields('Product', [
'currencyPrice' => [
'type' => 'String',
'description' => __('Regular price (β¬)', 'custom-sale-price'),
'resolve' => function (\WPGraphQL\WooCommerce\Model\Product $product, $args, $context, $info) {
$product = wc_get_product($product->ID);
return $product->get_meta('_alg_currency_switcher_per_product_regular_price_EUR') ? $product->get_meta('_alg_currency_switcher_per_product_regular_price_EUR') . 'β¬' : '';
}
],
]);
register_graphql_fields('Product', [
'currencySale' => [
'type' => 'String',
'description' => __('Sale price (β¬)', 'custom-sale-price'),
'resolve' => function (\WPGraphQL\WooCommerce\Model\Product $product, $args, $context, $info) {
$product = wc_get_product($product->ID);
return $product->get_meta('_alg_currency_switcher_per_product_sale_price_EUR') ? $product->get_meta('_alg_currency_switcher_per_product_sale_price_EUR') . 'β¬' : '';
}
],
]);
register_graphql_fields('Product', [
'language' => [
'type' => 'String',
'description' => __('language', 'lang-code'),
'resolve' => function (\WPGraphQL\WooCommerce\Model\Product $product, $args, $context, $info) {
$url = $product->get_permalink();
$isItPL = strpos($url, '/pl/');
if ($isItPL !== false) {
//url contains 'pl'
return 'PL';
} else {
//english
return 'EN';
}
}
],
]);
});
Quite complicated isnβt it?
Thatβs why our theme comes packed with WPGraphQL ACF extension to simplify the process. We have been testing various configurations with various plugins, but lots of errors arise and we only chose the most stable and efficient ones while trying to find an easy way of making the GraphQL schema flexible, we developed the ACF textarea input to handle JSON objects and it is the suggested way of extending the schema making it futureproof and personalised without affecting the system.
Suggested schema extension workflow
Here is a guide on how to extend the schema that way:
- Go to ACF and add a field or a group of fields
- The field will auto register in WPGraphQL thanks to wpgraphql-acf plugin.
- Now in the frontend You can write a component that will query the option saved in the postβs custom field using only JavaScript. Check this post for how to use the GraphiQL IDEβs to monitor data from the backend.
- Example query for a ACF attached to homepage and named Hero from the frontend:
export const query = graphql`
{
wpPage(isFrontPage: { eq: true }) {
content
homepage {
hero {
isColumns
cta1 {
target
title
url
}
cta2 {
target
title
url
}
heading
kicker
text
}
}
}
}
Homepage has the hero component implemented with ACF (this one is imported at setup) and that way You can implement any other custom fields.
StaticQuery vs GraphQL query
In Gatsby, StaticQuery is used inside React components and can only be used in non-page components. It runs at build time and doesnβt accept variables. On the other hand, the GraphQL page query is used in page components, supports variables, and is passed via pageContext
. Page queries allow more flexibility, while StaticQuery is ideal for fetching small, static site-wide data.
Example react component fetching the data and passing it down in the tree:
export default function HomepageHero(props) {
return (
{props.data?.wpPage?.homepage?.hero?.isColumns[0].toString() ===
"True" ? (<ColumnsHero props={props.data?.wpPage?.homepage?.hero} />) : (<FullSizeHero props={props.data?.wpPage?.homepage?.hero} />)}
);
}
Other available WPGraphQL extensions
There are also other extensions available for popular plugins to help you deliver extended schema more quickly and a complete list of available community extensions can be found here (some are already included into the theme).
WARNING: Activating any of not included comes with a risk of breaking the setup, we only give licence for extending WPGraphQL schema with the included plugins that have been tested against compatibility issues and their exact versions listed in requirements. If it happens that You test any of those not included feel free to report compatibility with the setup, as that can help You and other users get new features and improve the theme.
- https://wordpress.org/plugins/wp-gatsby/ β included
- https://github.com/wp-graphql/wpgraphql-acf β included
- https://woographql.com/ β included
- https://github.com/wp-graphql/wp-graphql-jwt-authentication β included
- https://github.com/wp-graphql/wp-graphql-smart-cache β included
- https://github.com/funkhaus/wp-graphql-cors β included
- https://github.com/ashhitch/wp-graphql-yoast-seo β not included (present in alpha β coming soon)
- https://github.com/valu-digital/wp-graphql-polylang β not included (present in alphaβ coming soon)
- https://github.com/AxeWP/wp-graphql-rank-math β not included (tested, considering β coming soon)
- https://github.com/toriphes/wp-graphql-ninja-forms β not included (not tested)
- https://github.com/wp-graphql/wp-graphql-custom-post-type-ui β (not tested)
- https://github.com/wp-graphql/wp-graphql-tax-query β not included (not tested)
- https://github.com/wp-graphql/wp-graphql-meta-query β not included (not tested)
- https://github.com/DalkMania/wp-graphql-cpt β not included (not tested)
- https://github.com/matepaiva/wp-graphql-crb β not included (not tested)
- https://github.com/TylerBarnes/wp-graphql-enable-all-post-types β not included (not tested)
- https://github.com/hsimah-services/wp-graphql-mb-relationships β not included (not tested)
- https://github.com/andrenoberto/wp-graphql-polls β not included (not tested)
- https://github.com/DalkMania/wp-graphql-mb β not included (not tested)
- https://github.com/izzygld/wp-graphql-google-schema β not included (not tested)
- https://github.com/builtbycactus/total-counts-for-wp-graphql β not included (not tested)
- https://github.com/hsimah-services/wp-graphql-metabox β not included (not tested)
- https://github.com/darylldoyle/wp-graphql-offset-pagination β not included (not tested)
- https://github.com/hsimah-services/wp-graphql-facetwp β not included (not tested)
- https://github.com/rburgst/wp-graphql-wpml β not included (not tested)
- https://github.com/valu-digital/wp-graphql-lock β not included (not tested)
- https://github.com/wp-graphql/wp-graphql-buddypress β not included (not tested)
- https://github.com/Quartz/wp-graphql-persisted-queries β not included (not tested)
- https://github.com/roborourke/wp-graphql-meta β not inclued (not tested)
- https://github.com/harness-software/wp-graphql-posts-to-posts β not included (not tested)
- https://github.com/harness-software/wp-graphql-gravity-forms β not included (not tested)
- https://github.com/pristas-peter/wp-graphql-gutenberg β not included (tested not compatibile!)
- https://github.com/moonmeister/wp-graphql-seopress β not inclued (not tested)
- https://github.com/ashhitch/wp-graphql-send-mail β not included (not tested β considering testing)
- https://github.com/Quartz/wp-graphql-content-blocks β not included (tested and is compatible)
- https://github.com/wp-graphql/wp-graphql-dad-jokes β not included (not tested)