Skip to content

Enhancement: Add support for Server-Side Tracking / Custom Gateway routing (transport_url) #3266

@hardik18882

Description

@hardik18882

User story

As a WooCommerce merchant or agency using First-Party Server-Side Tracking (such as Cloudflare Google Tag Gateway or GTM Server-Side), I want the plugin to route its Google Ads tracking tags through my custom first-party domain so that my conversion tracking is accurate, respects ITP/ad-blockers, and does not result in double-counted conversions.

Is your feature request related to a problem?

Yes. As the industry moves toward Server-Side tracking to combat ITP and ad blockers (as officially recommended by Google), we are finding that the Google Listings & Ads plugin is structurally incompatible with these setups.

Currently, the plugin hardcodes the base configuration string and lacks a filter to inject a custom transport_url or server_container_url.

When a merchant uses a First-Party Tag Gateway, the gateway successfully intercepts the main checkout.min.js script. However, because the base config lacks the transport_url parameter, the plugin’s inline scripts and companion pixels (like 1p-conversion) bypass the gateway entirely and fall back to hitting googleadservices.com directly. This results in two completely separate initiator chains firing simultaneously for every order, artificially inflating ROAS and double-counting conversions in Google Ads.

How to reproduce the problem

  1. Install and configure the Google Listings & Ads plugin with Conversion Tracking active.
  2. Set up a First-Party Tag Gateway (e.g., Cloudflare Google Tag Gateway) to route Google tags through a first-party subdirectory like https://example.com/gateway/.
  3. Complete a test purchase and inspect the browser's Network Tab on the Order Received page.
  4. Observe Chain 1: The primary conversion script successfully routes through the first-party gateway (/gateway/...).
  5. Observe Chain 2: Simultaneously, companion pixels (like 1p-conversion) bypass the gateway and fire directly to google.com/pagead/... because the base config lacks routing instructions.

Describe the solution you'd like

Please allow developers to modify the base gtag config to include Server-Side routing parameters.

Either:

  1. Developer Hook (Quickest/Preferred): Wrap the return in get_gtag_config() with a WordPress filter (e.g., apply_filters( 'woocommerce_gla_gtag_config_params', ... )) so developers can natively append "transport_url": "https://example.com/gateway/" to the config array.
  2. Native UI Feature: Add a text field in the plugin settings for "Server-Side Container URL", which automatically appends the transport_url parameter to the global gtag config.

Describe alternatives you've considered

Currently, the only workaround for advanced tracking setups is to use the woocommerce_gla_disable_gtag_tracking filter to completely kill the plugin's tracking capabilities, and rely entirely on third-party data layer plugins (like GTM4WP) to handle the routing via Google Tag Manager.

Technical

In src/Google/GlobalSiteTag.php, the configuration string is strictly hardcoded within the get_gtag_config() method:

protected function get_gtag_config( string $ads_conversion_id ) {
	return sprintf(
		'gtag("config", "%1$s", { "groups": "GLA", "send_page_view": false });',
		esc_js( $ads_conversion_id )
	);
}

Because there is no apply_filters() hook wrapped around this return statement, developers are completely locked out from injecting the transport_url parameter.

Acceptance criteria

  • The base gtag('config', ...) output can be modified via a WordPress filter or a plugin setting to include additional parameters like transport_url.
  • When a custom transport_url is applied, all Google Ads conversion hits and companion pixels successfully route through the defined first-party domain without falling back to default Google endpoints.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions