LW IT Solutions logo LW IT Solutions logo LW IT Solutions
« Blog Overview /Digital Analytics/Tutorials / Tutorial: page_location, URL Fragments and Server Requests
Read this article in other languages:

Tutorial: page_location, URL Fragments and Server Requests

Tutorial: page_location, URL Fragments and Server Requests

Management Summary

Website analytics identifies viewed pages using an address sent by the website, which need not contain everything shown in the browser’s address bar. The part after # often identifies a section or application view and is omitted from the normal page request, although website code can send it separately. This matters for clear page reports and avoiding unwanted personal information in analytics. Sites that switch views without reloading also need consistent counting so each completed change is represented once.

Contents
  1. From the address bar to the request
  2. What the GA4 dimensions describe
  3. Length and privacy before transmission
  4. Single-page applications (SPAs): measurement after a completed transition
  5. Questions and answers
  6. Sources

A browser address, an HTTP page request and a GA4 event are different representations. The fragment after # is omitted from the request for the page. JavaScript can still read that fragment and send the value in a separate request.

GA4 does not include the fragment by default. Google’s pageview documentation explicitly states this exception to location.href. A custom page_location override can change the submitted value; the address bar alone does not establish what reached Analytics.

URL, collection and reporting are separate layers.
URL, collection and reporting are separate layers.

From the address bar to the request

For https://shop.example/checkout?page=2#payment, the scheme is https, the host is shop.example, the path is /checkout, the query is page=2 and the fragment is payment. More general URLs can also contain a port or user information.

The page request targets /checkout?page=2. HTTP/1.1 normally carries the host name and, when required, port in Host and the target in the request line; HTTP/2 and HTTP/3 use corresponding pseudo-headers. A request for /#/catalog therefore does not tell the page server which hash route was selected. Changes between hash routes need not request another document at all. Access logs cannot count those transitions from document requests alone.

What the GA4 dimensions describe

The following example assumes the documented default, a valid URL and no custom rewrite or redaction. The dimensions are views of collected event data, not four independent collection systems.

DimensionDefault example
Hostnameshop.example
Page locationhttps://shop.example/checkout?page=2
Page path + query string/checkout?page=2
Page path/checkout

A custom override containing a fragment requires its own check of the outgoing event and the report or export used. The default table does not guarantee how every reporting surface handles arbitrary supplied fragments. A stable, non-personal route name or an approved virtual path is often clearer for hash routing.

Query values can split otherwise identical pages into separate rows. The actual result also depends on redaction, rewriting and reporting. A path-based dimension can group pages without deleting campaign information from collection. A custom route_name needs an event-scoped custom dimension when used in ordinary GA4 reports.

Length and privacy before transmission

Google specifies a maximum of 1,000 characters for page_location. A longer value is outside that limit; silent, reliable truncation is not a supported design assumption. Short, valid, meaningful URLs are preferable to cutting an arbitrary string, which can destroy route or parameter semantics.

Dropping query parameters by name is not a complete privacy filter: paths, allowed parameter values, fragments and titles may also contain personal data. Google data redaction is an additional control, not a guarantee that every personal value is detected. A local length check can record only the length; printing the first 120 URL characters may itself expose sensitive information.

Removing UTM parameters or click identifiers before campaign processing can affect acquisition reporting. An initial tag receiving the raw address is not a general solution when that address contains personal data. Approved campaign handling and privacy-safe page identifiers need a coordinated design and tests; explicit campaign fields are not a universal substitute for auto-tagged click identifiers.

Single-page applications (SPAs): measurement after a completed transition

Single-page applications replace the visible content without loading a whole new document for every screen. Automatic history-based measurement already exists. A custom History API wrapper is therefore neither always necessary nor proof that the new page title is ready. pushState() does not fire hashchange; a URL change also does not establish that an asynchronous route finished rendering.

A useful rule for the application is one route_ready notification after a real screen transition has completed. The example below belongs in application code, with one call after the new screen and its title are ready. The two approved route keys and English display titles are illustrative and need adaptation to the actual route catalogue. Unknown routes and a missing or false permission value are rejected.

JavaScript
function reportRouteReady(routeKey, measurementAllowed) {
  var routes = {
    catalog: { path: "/catalog", title: "Catalog" },
    checkout: { path: "/checkout", title: "Checkout" }
  };
  if (measurementAllowed !== true ||
      !Object.prototype.hasOwnProperty.call(routes, routeKey)) {
    return false;
  }
  var route = routes[routeKey];
  window.dataLayer = window.dataLayer || [];
  window.dataLayer.push({
    event: "route_ready",
    route_name: routeKey,
    page_location: new URL(route.path, location.origin).href,
    page_title: route.title
  });
  return true;
}

This helper sends no request by itself. The integration must supply the current measurement permission and stop calls on withdrawal; the boolean does not replace consent handling for other tags. In GTM, a Custom Event trigger for route_ready can drive a GA4 page_view tag, using Data Layer Variables for the three supplied fields. Values must also stay coherent on subsequent events. The helper intentionally does not read raw URLs or titles. The mapped URLs contain no query or fragment; the example is not a complete acquisition implementation.

The router must provide exactly one call per counted transition, including the agreed initial-screen policy. A table-of-contents jump is not automatically a screen view. Identical routes can still represent a deliberate revisit, so URL equality alone is not a universal deduplication rule. The previous approved virtual URL also needs consideration as page_referrer for navigation analysis.

For fully manual pageviews, the initial automatic pageview and enhanced measurement’s history pageviews need separate disabling. send_page_view: false alone does not disable history-based pageviews. Acceptance checks include initial load, forward/back navigation, anchors, repeated routes, consent changes and one intended event per transition. Tag Preview, outgoing requests and DebugView answer different questions.

Questions and answers

Can a server-side container remove a fragment?

Yes, if a client explicitly included the fragment as event data. The container can change or exclude that value before forwarding. This cannot undo receipt at the endpoint or logging before transformation. Values that must stay on the device require removal before the outbound request.

Can a server redirect translate a hash route into a path?

Not from the page request alone. A redirect from / to /app/ without its own fragment normally preserves the original fragment under HTTP semantics. Client-side route mapping can translate approved old routes to new paths. A History API replacement also requires the server to serve the resulting path on reload; a location replacement performs navigation. Measurement should start after the intended mapping, with an explicit reporting comparison across the migration.

Does a fragment make personal data safe?

No. Scripts can read and transmit fragments. The lack of a fragment in the document request is a narrow protocol property, not a privacy guarantee.

Sources

Lukas Wojcik

Lukas Wojcik

Systems architect and technology enthusiast specializing in scalable tracking solutions, GMP Stack (GA4 & GTM), and robust backend architectures. Advocate for clean code and privacy-first design.

Get in touch

A question or an idea for a web project? Tell me a little about it. This form uses reCAPTCHA to protect against spam.

Write a comment

Differing figures from other accounts and questions about the setup are welcome here.

The email address is not published. Required fields are marked with an asterisk.