Skip to main content

Hooks and Filters

Role

ReactWP exposes a small set of starter-level filters that projects are expected to use instead of patching runtime internals directly.

These filters are some of the most important extension points in the starter.

Main Public Filters

  • rwp_system
  • rwp_bootstrap
  • rwp_route_payload
  • rwp_wp_head
  • rwp_critical_fonts
  • rwp_critical_medias
  • rwp_no_critical_medias
  • rwp_allowed_rest_routes

rwp_system

Use this filter to extend or alter the system payload.

Signature:

add_filter('rwp_system', function($system){
// ...
return $system;
});

Use it for:

  • extra URLs
  • environment flags
  • theme-level runtime settings

rwp_bootstrap

Use this filter to extend the full bootstrap payload before it is injected into the page.

Signature:

add_filter('rwp_bootstrap', function($payload, $route){
// ...
return $payload;
}, 10, 2);

Use it when you need to add project-wide frontend data.

rwp_route_payload

Use this filter to modify the normalized route payload before it is returned.

Signature:

add_filter('rwp_route_payload', function($payload, $object){
// ...
return $payload;
}, 10, 2);

Use it for:

  • adding route-level data
  • changing route-level flags
  • augmenting data, seo, or other payload fields

$object can be a:

  • WP_Post
  • WP_Term
  • WP_User
  • null for 404 payloads

Example: route a query-string variant to a dedicated template:

add_filter('rwp_route_payload', function($payload, $object){

$query = isset($payload['query']) && is_array($payload['query'])
? $payload['query']
: [];

if(!array_key_exists('s', $query)){
return $payload;
}

$search_term = trim((string)$query['s']);

$payload['type'] = 'search';
$payload['template'] = 'Search';
$payload['pageName'] = $search_term !== ''
? 'Search: ' . $search_term
: 'Search';

$payload['data']['searchTerm'] = $search_term;
$payload['data']['isSearchRoute'] = true;

return $payload;

}, 10, 2);

This works because ReactWP treats pathname + search as route identity.

The array_key_exists('s', $query) check is important if you want ?s= to use the same template as ?s=test.

rwp_wp_head

Use this filter to add or change head tags that must work both:

  • on direct page load
  • after React navigation

Signature:

add_filter('rwp_wp_head', function($wp_heads, $context = []){
// ...
return $wp_heads;
}, 10, 2);

See Head and SEO for the full behavior and the $context structure.

rwp_critical_fonts

Use this filter to define the critical font groups exposed to the loader runtime.

Signature:

add_filter('rwp_critical_fonts', function($fonts){
// ...
return $fonts;
});

Typical shape:

add_filter('rwp_critical_fonts', function($fonts){

$fonts['all'] = [
'400 1rem "Suisse Intl"',
'600 1rem "Suisse Intl"',
];

$fonts['home'] = [
'700 1rem "Suisse Intl"',
];

return $fonts;

});

rwp_critical_medias

Use this filter to register critical media groups for the loader runtime.

Signature:

add_filter('rwp_critical_medias', function($medias){
// ...
return $medias;
});

Each group entry can include:

  • type: image, video, or audio
  • src: the main source URL
  • target: a selector, a DOM node, or an array of selectors/nodes
  • sources: optional alternative sources with their own attributes such as media, type, or sizes
  • any DOM props that make sense for the rendered element, such as alt, className, poster, muted, loop, controls, autoplay, or playsInline

Example:

add_filter('rwp_critical_medias', function($medias){

$medias['home'] = [
[
'type' => 'image',
'src' => '/wp-content/uploads/2026/04/hero-desktop.jpg',
'target' => [
'#hero .media-slot',
'#hero .media-slot--fallback'
],
'alt' => 'Hero image',
'className' => 'hero-image',
'sources' => [
[
'src' => '/wp-content/uploads/2026/04/hero-mobile.jpg',
'media' => '(max-width: 767px)'
],
[
'src' => '/wp-content/uploads/2026/04/hero-desktop.jpg',
'media' => '(min-width: 768px)'
]
]
]
];

return $medias;

});

During the critical display phase, ReactWP downloads the entry, resolves the target, renders the right media element, and only then lets the route finish its critical reveal.

rwp_no_critical_medias

Use this filter to register deferred media groups.

Signature:

add_filter('rwp_no_critical_medias', function($medias){
// ...
return $medias;
});

For both media filters, ReactWP expects grouped arrays keyed by media group name.

rwp_allowed_rest_routes

ReactWP restricts REST access by default and lets specific routes through.

By default:

  • admins keep normal REST API access
  • non-admin users and guests are blocked
  • any route listed here stays accessible

Use this filter to allow additional public REST routes.

Signature:

add_filter('rwp_allowed_rest_routes', function($routes){
$routes[] = '/my-plugin/v1/public-endpoint';
return $routes;
});

Use it only when a route must remain accessible outside the admin-only REST surface.

Default Theme Examples

The default theme already exposes starter-level examples in:

  • src/themes/reactwp/template/functions.php

That file is the recommended place for project-specific filter usage.

Recommendation

When possible:

  • use these filters first
  • keep runtime internals stable
  • keep project customizations in the theme or project-level plugin layer