Menu
Instrumentation and self-hosting

How to Group Dynamic SaaS URLs into Product Pages and Features

Learn how to normalize dynamic SaaS routes, group them into stable product pages and features, handle query parameters, protect sensitive data, and preserve historical analytics.

Why dynamic URLs break product analytics

A SaaS application can generate a new URL for every company, report, project, task, user, document, integration, or saved view. That is useful for navigation, permissions, and deep links. It is usually a poor default identity for product analytics.

Consider these observed routes:

/companies/128/reports/451
/companies/931/reports/883
/projects/abc123/tasks/789
/users/42/settings
/reports/451?tab=history
/reports/451?token=secret-value

A raw page-view report may treat every string as a different page. The first two routes then look unrelated even though both represent the same product surface: a report detail page inside a company. The task route produces a new “page” for every task. The settings route may expose a user identifier. The two report URLs may split one page by tab state, while the final URL contains a value that should not become analytics data at all.

When dynamic URL tracking is left unmodeled, several distortions follow:

  • Thousands of apparent pages. Every record-specific path becomes a separate row, producing high-cardinality reports that are difficult to scan or aggregate.
  • Fragmented adoption. Ten companies can use the same feature, yet each appears to have used a different page because their record IDs differ.
  • Misleading top-page lists. Stable shell pages rise to the top while important record-detail workflows disappear across many low-volume paths.
  • Unusable trends. A new route structure or tenant prefix can look like a sudden launch, collapse, or migration even when product behavior did not change.
  • Accidental collection of identifiers or secrets. Query strings, slugs, document names, email addresses, invite codes, and tokens may enter analytics, logs, exports, or session evidence.
  • Broken comparisons after route changes. Renaming /reports/:id to /analytics/reports/:id can split one long-running product feature into two unrelated time series.

The solution is not simply to delete everything dynamic. A plan to normalize URLs for analytics should create a URL taxonomy for SaaS analytics that preserves useful evidence while assigning every observation to a stable product meaning.

Keep raw, normalized, grouped, and area levels separate

A maintainable model distinguishes four levels. Each level should have a clear question and should not silently substitute for another.

Four page levels and the questions they answer
Level Example Primary question Typical use
Raw URL /companies/128/reports/451?tab=history What route was observed before analytical normalization, after required privacy filtering? Debugging ingestion, investigating a specific visit, testing rules, and tracing classification evidence.
Normalized raw page /companies/:company_id/reports/:report_id Which stable route pattern did the observation match? Technical route analysis, action-level evidence, QA, and detection of route changes.
Grouped page or feature Report details Which meaningful product page, feature, or workflow did the user reach? Adoption, engagement, trends, company and user comparisons, and product flows.
Product area Reporting Which broader part of the product contains this grouped page? Portfolio-level product structure, adoption breadth, navigation, and executive summaries.

The word “raw” should not mean “store every character the browser exposed.” A useful raw layer is the most detailed privacy-safe route evidence your system intentionally retains. If a URL contains a token, email address, confidential search term, or customer document name, the unsafe value should not be preserved merely because analysts may want to debug it later.

A dynamic SaaS URL passes through privacy filtering, route normalization, grouped-page classification, and product-area assignment.
Useful page analytics keeps the evidence chain while removing unsafe values and collapsing record-specific routes into stable product entities.

Understand which URL components carry product meaning

The WHATWG URL Standard and RFC 3986 describe URLs as structured components rather than one opaque string. Product analytics should evaluate those components deliberately.

How common URL components affect SaaS page grouping
Component Example Analytical treatment
Scheme https Usually an environment or transport concern, not a product-page identity. Do not split pages by http versus https unless the difference is intentional and meaningful.
Host app.example.com or atlas.example.com May identify an application, environment, region, or tenant. Normalize tenant subdomains where appropriate, but keep separate products or environments distinct.
Path /companies/128/reports/451 Usually the main source of route meaning. Analyze path segments in context rather than replacing every variable-looking segment.
Query parameters ?tab=history&page=2 Classify by analytical meaning: ignore noise, preserve selected safe state, or remove sensitive values before storage.
Hash fragment #permissions or #/projects/128 Often local UI state, but some applications use it for routing. A client-side tracker can see fragments even though they are not sent in the HTTP request, so privacy treatment must be explicit.
Locale prefix /fr/reports/451 Usually normalize to a placeholder or remove from page identity, then keep locale as a separate safe property if it is analytically useful.
Tenant or workspace prefix /workspaces/atlas/reports/451 Usually replace with a placeholder for page analysis while associating the event with the correct company or workspace through stable identity data.
Dynamic ID 451, abc123, or a UUID Usually replace with a named placeholder when it identifies one instance of a resource.
Slug design or getting-started May be either an identifier or meaningful content. Decide from product semantics and route metadata, not shape alone.
Tab or mode ?tab=history or ?mode=compare May justify a grouped subpage, a page-state property, or no separate classification, depending on the question.
Filter, sort, and pagination ?status=open&sort=created&page=3 Often changes a list view rather than the product page. Usually remove from page identity and model only selected safe state needed for analysis.
Search term ?q=quarterly+forecast Potentially sensitive free text. Prefer a separate, reviewed event or coarse classification instead of unrestricted URL capture.
Authentication value ?token=secret-value Remove before persistence. Do not use the token as a page property, grouping key, or debugging field.

Most SaaS route analytics should focus on route meaning, not every possible URL variation. The goal is a stable product identity, with selected state modeled separately when it helps answer a real question.

Detect dynamic path segments without erasing product meaning

Dynamic segments commonly appear as numeric IDs, UUIDs, database keys, prefixed identifiers, opaque tokens, user-readable slugs, dates, locale codes, workspace identifiers, or nested records. Some are easy to recognize. Others are ambiguous.

Strong signals that a segment is probably dynamic

  • A framework route template marks the segment as a parameter.
  • The value matches a UUID or a documented internal ID format.
  • The segment appears after a resource noun and has very high cardinality, such as /reports/451, /reports/883, and thousands more.
  • The value uses an opaque or prefixed key such as proj_7f92a1 or usr_01J4....
  • The same surrounding static segments render the same page component for many values.
  • The application already knows the parameter name, such as reportId, workspaceId, or taskId.

Segments that require context

Shape alone is not enough. These routes illustrate why an automatic “replace every non-static segment” rule can be dangerous:

  • /settings/billing contains stable semantic segments. Replacing billing would erase a meaningful page.
  • /reports/2026 may identify a report record, but it may also represent a year view or reporting period.
  • /teams/design may use a team slug that should be normalized, or it may represent a stable product workspace that the team intentionally analyzes separately.
  • /docs/getting-started should not become /docs/:slug when individual documentation pages are analytically meaningful.
  • /integrations/github may be one member of a finite product module list. Replacing github with :provider can be useful at the normalized-route level, while grouped pages may still retain separate integration identities if the product question needs them.
  • /reports/monthly could be a saved report slug, an enum-like report mode, or a static route. The adjacent code and route declaration know more than the string does.

Practical heuristics

  1. Prefer explicit route metadata. Use the route name or template known by the application or server whenever it is available.
  2. Use semantic placeholders. Prefer :company_id and :report_id to a generic :id; named placeholders make nested routes reviewable.
  3. Check cardinality and repetition. A segment with thousands of values between the same static neighbors is probably an identifier. A segment drawn from a small, documented set may be product state.
  4. Maintain finite allowlists for semantic values. Known values such as billing, permissions, history, or supported locales should not be swallowed by a broad identifier regex.
  5. Inspect what the route renders. Different values that render the same component and task usually belong to one normalized route; values that lead to distinct workflows may deserve separate grouped pages.
  6. Sample production-like routes. Test common, rare, legacy, localized, and malformed examples before enabling a rule.
  7. Keep a safe fallback. When the system is unsure, classify the observation as unclassified or preserve a conservative normalized path rather than guessing aggressively.

Prefer route templates over guesses from the final URL

Modern routers already know which parts of a route are static and which are parameters. When teams group pages by URL pattern, this route metadata is usually a better input than the rendered string alone. Their syntax differs, but the underlying idea is similar:

/companies/:companyId/reports/:reportId
/projects/[projectId]/tasks/[taskId]
/users/{user_id}/settings

React Router and Vue Router use colon-style dynamic segments, Next.js and SvelteKit commonly use bracketed file-system segments, while server frameworks such as Django and ASP.NET Core expose route converters or templates. A product analytics implementation does not need to standardize every framework on one source-code syntax. It needs a stable internal representation.

OpenTelemetry’s HTTP semantic conventions provide a useful principle: a route should be a low-cardinality application template, and the raw URI path should not substitute for it when the framework has not supplied route information. The related event conventions likewise keep event names stable rather than embedding changing values in them. Both principles apply well beyond infrastructure telemetry.

Possible sources of page identity

  • Explicit route name emitted by the application. For example, report.details or settings.api_keys. This is usually the most stable source when the team maintains it deliberately.
  • Router metadata. A matched route record, route ID, component metadata, or file-system route template can identify dynamic segments without inspecting their values.
  • Server-side route template. A backend can expose the matched endpoint template or attach it to a page-view payload.
  • Client-side rule matching. A maintained rule set can classify the privacy-safe route after navigation.
  • Maintained regex rules. Useful for legacy systems or routes that cannot provide templates, but they require priority, anchoring, conflict tests, and ownership.
  • Fallback normalization. Conservative heuristics can replace obvious IDs while leaving uncertain segments unclassified for review.

The application-provided source should be stable across localization, page-title changes, record names, and asynchronous content. Display labels can change. Stable route and grouped-page IDs should not.

A framework-neutral route contract

The following is a conceptual payload, not a Hymetry API or tracker contract. It shows the type of information an application can make available to any analytics pipeline:

{
  "navigation_id": "nav_01J8EXAMPLE",
  "safe_observed_path": "/companies/128/reports/451",
  "route_template": "/companies/:companyId/reports/:reportId",
  "route_name": "report.details",
  "safe_page_state": {
    "tab": "history"
  }
}

The stable route name and template carry identity. The observed path remains available as privacy-safe evidence. Selected page state stays separate so it does not multiply the normalized route unnecessarily.

Classify query parameters by meaning, not by a universal strip-or-keep rule

To normalize URL parameters safely, first classify what they mean. Query parameters can represent acquisition metadata, interface state, workflow steps, search input, customer identifiers, or secrets. The correct choice depends on the analytical question and the sensitivity of the value.

Three query-parameter categories for page analytics
Category Common examples Recommended treatment
Usually remove or ignore for page identity utm_*, click identifiers, sort, page, temporary UI state, cache-busting values Drop from the normalized URL. Keep only separately governed acquisition or interface properties when they are genuinely needed.
May represent meaningful page state tab, mode, step, compare, module Use a reviewed allowlist. Model the value as a safe property, a grouped subpage, or a separate workflow step when it changes the analytical meaning.
Must be removed or protected tokens, authorization codes, email addresses, customer identifiers, document names, unrestricted search text, authentication values Remove before persistence where possible. Do not retain merely to improve debugging or grouping.

Example: ?tab=history

The route /reports/451?tab=history can be modeled in several defensible ways:

  • Normalize it to /reports/:report_id, group it as Report details, and store tab=history as a safe page-state property.
  • Normalize it to the same route but group the state as a separate Report history page when the tab is a substantial task with its own adoption question.
  • Ignore the tab entirely when it is a minor visual variation that should not affect product analysis.

These options answer different questions. The important point is that ?tab=history should not automatically create a brand-new normalized URL, and it should not automatically be deleted without review.

Prefer an allowlist for retained state

A query-parameter blocklist eventually misses a new secret, customer field, or free-text value. A safer approach is to remove query parameters by default and allow only reviewed keys with constrained values. For example, tab may be allowed only when its value is one of overview, history, or permissions.

Do not assume that query-parameter order, repetition, defaults, or encoding can be normalized safely in every application. The generic URL syntax does not define your product’s business equivalence rules. Canonicalize only where the application confirms that two forms mean the same thing.

Example: ?token=secret-value

The token must not become part of the raw evidence, normalized route, page name, event property, error message, or rule-preview log. The safe classification can still be:

Observed by browser: /reports/451?token=secret-value
Privacy-safe route: /reports/451
Normalized raw page: /reports/:report_id
Grouped page: Report details
Product area: Reporting

Track logical navigation in single-page applications

A traditional page-view tracker can listen for a full document load. A single-page application may load the document once and then change routes many times without another full reload. Reliable single-page application route tracking therefore needs to observe logical navigation.

Navigation sources to account for

  • Initial browser load. The first rendered route should produce one page view after the application has resolved its route and privacy-safe classification.
  • history.pushState(). The application may add a new history entry and change the URL without reloading the document.
  • history.replaceState(). The application may replace the current history entry for redirects, canonicalization, or state updates.
  • popstate. Browser Back and Forward navigation can activate a previous same-document history entry.
  • Framework navigation hooks. Router-level “after navigation” or route-commit events often provide a more reliable signal than patching browser methods directly because they also expose the matched route.
  • Hash-based routes. Older or embedded SPAs may encode the route after #; hash changes need explicit handling when they represent navigation.

The HTML Living Standard defines the browser’s session-history APIs. One subtlety matters for analytics: calling pushState() or replaceState() does not itself fire popstate. A tracker that listens only for popstate can miss forward navigation created by the application.

Avoid duplicate virtual page views

Duplicate page views often appear when an application combines several mechanisms:

  • automatic tracking on browser-history changes;
  • manual page-view calls from the router;
  • a patched pushState() listener;
  • a component effect that runs again after data loads;
  • both an initial-load event and a second “route ready” event for the same navigation.

Google Analytics’ page-view guidance explicitly warns that manual page views can duplicate automatic page views if both are enabled. The same engineering risk applies to any analytics stack.

Choose one primary navigation source, assign a navigation identifier when possible, and deduplicate repeated notifications for the same committed route. A page-view event should represent a logical page transition, not every render, data refresh, title update, or state mutation.

Framework-neutral navigation pseudocode

This conceptual example is not a framework recipe and not a Hymetry SDK contract:

function onNavigationCommitted(navigation) {
  const safeInput = privacyFilter(navigation.url);

  const page = classifyPage({
    safeUrl: safeInput.url,
    routeName: navigation.routeName,
    routeTemplate: navigation.routeTemplate
  });

  analytics.recordPageView({
    navigationId: navigation.id,
    normalizedPage: page.normalizedPage,
    groupedPageId: page.groupedPageId,
    productAreaId: page.productAreaId
  });
}

router.afterNavigation(onNavigationCommitted);

In a real implementation, use the router’s supported lifecycle and the analytics tool’s documented API. Do not copy a generic patch into production without tests for initial load, redirects, Back and Forward navigation, and duplicate notifications.

When a modal or panel behaves like a page

A URL-changing modal, drawer, or inspector can deserve page-like treatment when it is addressable, supports Back navigation, represents a distinct task, and appears in meaningful session flows. A lightweight confirmation dialog or tooltip usually belongs as an event, not a page.

Use the product question as the test: would the team reasonably ask which accounts adopted this surface, how users reached it, and what happened next? If yes, a grouped page may be appropriate. If the question is only whether a control was opened or confirmed, an event is usually clearer.

Design grouping rules as a versioned classification system

A page-grouping rule is part of the analytical data model, not a one-off text replacement. It determines which observations become comparable, which product entities appear in reports, and how a route change affects historical trends. The rule model therefore needs stable identity, deterministic precedence, tests, and ownership.

Useful rule fields

Concepts in a maintainable route-classification rule
Field Purpose
Stable rule ID Identifies the rule independently of its display name or current pattern so matches can be audited over time.
Project ID Scopes the rule to the correct application, environment, or analytical project.
Match pattern Stores the exact path, route template, regex, or named route the rule evaluates.
Match type Distinguishes exact, route-name, template, regex, prefix, or fallback logic.
Priority Resolves overlaps predictably. Higher specificity should not depend on the accidental order of rows in a database or configuration file.
Normalized route Defines the stable raw-page pattern, such as /companies/:company_id/reports/:report_id.
Grouped page or feature ID Links the route to a stable product entity such as Report details. Use a durable ID separately from the label users see.
Product area ID Rolls the grouped page into a broader area such as Reporting.
Active status Allows a rule to be retired without deleting its history.
Source Records whether the rule came from application metadata, a manual definition, an import, a suggestion, or a fallback process.
Created and updated timestamps Provide operational history and support review of recent changes.
Version or effective period Explains which classification applied to which observations and supports reproducible historical reporting.

It is also useful to attach the resulting matched_rule_id and classification_version to the classified page record. That makes a surprising aggregate traceable to the exact rule that produced it.

Use deterministic precedence

One reasonable precedence model is:

  1. Explicit application-provided route name or stable route metadata.
  2. An exact manually defined rule.
  3. A high-priority route-template rule.
  4. A maintained regex rule.
  5. A conservative safe fallback classification.
  6. An unclassified page that is monitored for review.

The exact order depends on the implementation. A team may decide that an approved manual exception should override application metadata, or that server route templates are more trustworthy than client route names. What matters is that the order is explicit, testable, and stable.

A precedence ladder resolves a page first from application route metadata, then exact, template, and regex rules before fallback classification.
The precise order varies by implementation, but specific, reviewable sources should normally win over broad inference.

Treat overlapping regex patterns as conflicts, not surprises

Suppose a specific rule matches ^/settings/api-keys$ and a broad rule matches ^/settings/[^/]+$. Both match the API keys page. If priority is implicit, a configuration reorder can silently move API keys into a generic Settings group.

Anchor regex patterns, assign explicit priorities, detect multiple matches in preview, and define a deterministic tie-breaker. Broad catch-all rules should usually have lower priority than exact or template-based rules. A rule editor should make the losing matches visible rather than hiding them.

Conceptual rule example

This object illustrates a maintainable rule shape. It is not a Hymetry API, database schema, or configuration format:

{
  "rule_id": "page_rule_report_details_v3",
  "project_id": "project_example",
  "match_type": "route_template",
  "match_pattern": "/companies/:companyId/reports/:reportId",
  "priority": 300,
  "normalized_route": "/companies/:company_id/reports/:report_id",
  "grouped_page_id": "report_details",
  "product_area_id": "reporting",
  "active": true,
  "source": "application_route_metadata",
  "effective_from": "2026-08-01T00:00:00Z",
  "version": 3
}

Practical URL grouping examples

The following routes are fictional. They show why normalization, product grouping, and privacy action should be reviewed together instead of handled by three unrelated systems.

Example rules for fictional SaaS routes
Observed URL Normalized raw page Grouped page or feature Product area Rule reason Privacy action
/companies/128/reports/451 /companies/:company_id/reports/:report_id Report details Reporting Both numeric segments identify records inside a stable nested route. Replace company and report identifiers in the normalized page; restrict access to any retained privacy-safe observed path.
/companies/128/settings/profile /companies/:company_id/settings/profile Company settings Administration The company segment is dynamic; settings/profile is stable product meaning. Normalize the company identifier. Do not derive company identity from the URL when a stable account ID is available separately.
/settings/billing?plan=pro&sort=price /settings/billing Billing Billing The route is stable. Sort order should not create another page; a reviewed plan value can be separate page state if needed. Remove unneeded query values. Allow only constrained, non-sensitive state that has a defined analytical use.
/settings/api-keys/key_9x7 /settings/api-keys/:key_id API keys Developer tools The final segment identifies one key record, while API keys is a meaningful security workflow. Replace the key record identifier and never capture key material, credentials, or copied secret values.
/search?q=person%40example.test /search Search Core product Free-text input is not page identity. Remove the query before persistence. Measure search use through a separately governed event or coarse, approved property if needed.
/fr/workspaces/atlas/reports/451 /workspaces/:workspace_id/reports/:report_id Report details Reporting The locale, workspace, and report vary; the product surface remains the same. Remove locale from page identity and keep it only as an approved property. Normalize workspace and report identifiers.
/reports/451?tab=history /reports/:report_id Report details Reporting The selected tab is meaningful state but does not necessarily define a new route. Allowlist history as safe state or map it to a reviewed subpage; remove all other unapproved query values.
/invite/accept?token=EXAMPLE_TOKEN /invite/accept Invitation acceptance Administration The path is a stable workflow. The token authorizes one invitation and has no analytical value. Remove the token before storage, logging, preview, export, or replay metadata.

Notice that one route can retain useful state without making that state part of the normalized URL. Likewise, a segment can become a placeholder at the normalized level while still supporting a more specific grouped page. The levels are related, but they are not the same field.

Worked B2B example: twelve routes become five stable product pages

Imagine a multi-tenant SaaS product with four customer companies: Atlas, Beacon, Cedar, and Dune. During one period, seven visits generate twelve page views. The browser-observed inputs include locales, workspace slugs, record IDs, a selected tab, and one example invite token that the privacy filter must remove before persistence.

Fictional browser-observed routes and their stable product classification
Company Visit Browser-observed input Normalized raw page Grouped page Product area
Atlas A-01 /en/workspaces/atlas/companies/128 /workspaces/:workspace_id/companies/:company_id Company overview Core accounts
Atlas A-01 /en/workspaces/atlas/reports/451 /workspaces/:workspace_id/reports/:report_id Report details Reporting
Atlas A-01 /en/workspaces/atlas/reports/451/edit /workspaces/:workspace_id/reports/:report_id/edit Report builder Reporting
Atlas A-02 /en/workspaces/atlas/settings/integrations/slack /workspaces/:workspace_id/settings/integrations/:provider Integration settings Integrations
Beacon B-01 /workspaces/beacon/companies/931 /workspaces/:workspace_id/companies/:company_id Company overview Core accounts
Beacon B-01 /workspaces/beacon/reports/883?tab=history /workspaces/:workspace_id/reports/:report_id Report details Reporting
Beacon B-02 /workspaces/beacon/settings/users /workspaces/:workspace_id/settings/users User management Administration
Cedar C-01 /fr/workspaces/cedar/reports/222 /workspaces/:workspace_id/reports/:report_id Report details Reporting
Cedar C-01 /fr/workspaces/cedar/reports/new /workspaces/:workspace_id/reports/new Report builder Reporting
Cedar C-02 /fr/workspaces/cedar/settings/integrations/github /workspaces/:workspace_id/settings/integrations/:provider Integration settings Integrations
Dune D-01 /workspaces/dune/companies/551 /workspaces/:workspace_id/companies/:company_id Company overview Core accounts
Dune D-01 /workspaces/dune/settings/users?invite_token=EXAMPLE_TOKEN /workspaces/:workspace_id/settings/users User management Administration

The example invite token appears only to show the browser input. A correct privacy filter removes it before the stored raw-route evidence, rule preview, or analytics record is created. The locale can be retained as a safe, separate property if the team needs a locale comparison. The selected history tab can likewise remain approved page state without producing another normalized route.

The classification result

How the twelve page views collapse into stable analytical entities
Normalized raw page Page views Grouped page Product area
/workspaces/:workspace_id/companies/:company_id 3 Company overview Core accounts
/workspaces/:workspace_id/reports/:report_id 3 Report details Reporting
/workspaces/:workspace_id/reports/:report_id/edit 1 Report builder Reporting
/workspaces/:workspace_id/reports/new 1 Report builder Reporting
/workspaces/:workspace_id/settings/integrations/:provider 2 Integration settings Integrations
/workspaces/:workspace_id/settings/users 2 User management Administration

The twelve browser-observed routes now produce six normalized raw pages, five grouped pages, and four product areas. The grouped-page totals are:

  • Company overview: 3 page views across Atlas, Beacon, and Dune.
  • Report details: 3 page views across Atlas, Beacon, and Cedar.
  • Report builder: 2 page views across Atlas and Cedar.
  • Integration settings: 2 page views across Atlas and Cedar.
  • User management: 2 page views across Beacon and Dune.

At the product-area level, Reporting receives 5 page views, Core accounts 3, Integrations 2, and Administration 2. The original seven visits and twelve page views have not changed. Only their analytical classification has.

Twelve observed routes from four fictional SaaS companies collapse into six normalized routes, five grouped pages, and four product areas.
Normalization changes classification, not the underlying visits. Teams gain stable adoption and flow analysis without losing the path back to source evidence.

What becomes analytically usable

Visit and page-view counts remain intact. The team still has seven visits and twelve page views. A normalized taxonomy prevents those twelve observations from appearing as twelve unrelated product pages.

Page adoption becomes interpretable. Using the simple reach definition “companies that used the grouped page divided by four active companies,” Company overview and Report details each reach 75% of companies, while Report builder, Integration settings, and User management each reach 50%. This is an illustration of page reach, not proof that a workflow was completed successfully.

Trend lines remain stable across records. A new report ID contributes to the same Report details trend instead of starting another one-row series. A route rename can also be mapped to the existing grouped-page ID when the product meaning has not changed.

Product-area breadth becomes visible. Atlas and Beacon each reached three product areas; Cedar and Dune each reached two. That is more useful for account-centric B2B analysis than asking whether each company visited a specific record URL.

Top pages stop being a list of records. Report details and Company overview emerge as the most widely reached grouped pages rather than twelve paths tied at one observation each.

Session flows become comparable. The example contains two Company overview → Report details transitions, two Report details → Report builder transitions, and one Company overview → User management transition. Those patterns would be invisible if every record URL had a unique page identity.

Investigation remains possible. A product manager can start from Report details, find the three affected companies, then inspect the specific normalized routes and visits. Grouping should compress the reporting dimension, not sever the evidence chain.

Use AI suggestions as reviewable proposals, not taxonomy truth

AI can help an analyst notice that hundreds of routes share a likely template, propose a human-readable grouped-page name, or suggest that several normalized routes belong to one product area. That can reduce clerical work, especially in a large legacy application. It does not remove the need to understand the product.

A useful suggestion workflow should be:

  • Reviewable. Show the sampled routes, proposed template, proposed grouped page, and affected observations before approval.
  • Testable. Run the suggestion against representative positive, negative, legacy, and sensitive examples.
  • Reversible. Preserve the prior rule version and provide a clear rollback path.
  • Constrained by current routes. Suggestions should be grounded in route metadata and observed privacy-safe examples, not invented product structure.
  • Accompanied by rationale or confidence where useful. Explain which segments varied, which static segments matched, and where ambiguity remains.
  • Treated as a suggestion. A product owner or analytics maintainer decides whether the grouping reflects a meaningful product entity.

Hymetry can use AI-assisted naming to suggest meaningful page structure, while manual page rules remain available. That is an assistance model, not a claim that every URL is automatically classified correctly or that generated names should be accepted without review.

Decide how rule changes affect historical comparability

A route taxonomy changes as the product changes. Teams rename pages, split one workflow into two, merge duplicate routes, correct an overly broad regex, or reorganize product areas. The key historical question is: when a rule changes today, should yesterday’s events be reclassified?

Approaches to historical page classification
Approach How it works Advantage Trade-off
Apply the current taxonomy retroactively Query or reclassify all privacy-safe historical routes with today’s rules. Historical reports reflect the team’s current understanding and remain easy to compare across the full period. Past dashboards can change without the underlying behavior changing, which weakens reproducibility.
Use effective-dated rules Each rule version applies only during a defined period. Reports reproduce the classification that was in force at the time. A continuous feature can be split when the taxonomy changes, making long-term trend interpretation harder.
Materialize classification at ingestion Store normalized, grouped-page, product-area, rule, and version IDs with each observation. Fast, explainable historical queries with a clear audit trail. Corrections require a backfill or a second classification rather than a simple rule edit.
Run full reprocessing Recompute classifications from retained privacy-safe evidence after a material taxonomy change. Produces one consistent current view when the source evidence and processing capacity exist. Can be operationally expensive and may rewrite previously reported numbers.
Preserve original and current classifications Keep the classification used at ingestion and optionally compute a current-taxonomy view alongside it. Supports both historical reproducibility and analysis using the current product model. Adds storage, processing, interface, and explanation complexity.

No approach is universally correct. A label correction from “Report detials” to “Report details” can usually preserve the same stable grouped-page ID and leave trends untouched. Splitting a generic “Settings” page into Billing, Permissions, and API keys is a material taxonomy change that may justify a documented backfill or an effective date.

For material changes, record what changed, why, who approved it, which route samples were affected, whether history was reprocessed, and how dashboards should be interpreted. Versioned rules and durable page IDs turn that explanation into part of the model instead of a note someone must remember.

Treat URL privacy and security as an ingestion requirement

URLs can contain far more than navigation structure. They may expose email addresses, invitation or password-reset tokens, authorization codes, customer names, internal IDs, search queries, document names, support-case text, file paths, or secrets copied into a filter. A useful taxonomy cannot compensate for unsafe capture.

OWASP’s guidance on information exposure through query strings explains that sensitive values can appear in browser history, server and proxy logs, referrer data, and other systems even when transport uses HTTPS. HTTPS protects data in transit; it does not make a sensitive query string safe to retain in analytics.

Practical controls

  • Remove sensitive values before persistence where technically possible. Filter the browser-observed URL before analytics storage, rule-preview logging, exports, replay metadata, or downstream processing.
  • Prefer allowlists to unrestricted query capture. Retain only reviewed keys with constrained values. Treat all other query values as absent unless a documented use requires them.
  • Separate identity from route strings. Associate a page view with a user and company through stable, governed identifiers rather than parsing email addresses, customer names, or tenant slugs from the URL.
  • Test with production-like examples. Include synthetic tokens, email-shaped values, customer-like slugs, encoded text, repeated parameters, and unusual path segments in privacy and classification tests.
  • Restrict raw-route access. The most detailed privacy-safe evidence should have narrower access than aggregate grouped-page reports, with access and export behavior intentionally designed.
  • Set intentional retention. Keep detailed route evidence only as long as it supports a defined analytical or operational need.
  • Treat query and fragment values explicitly. A URL fragment is not sent to a server in the HTTP request, but browser-side analytics code can still read and transmit it. Hash-based routes and fragment state require the same privacy review as query parameters.
  • Do not assume replay masking covers analytics fields. Masking a visible input or replay element does not automatically remove the same value from a URL, page title, event property, error, or network-derived field.
  • Do not log secrets for failed matches. An “unclassified URL” queue, debugging console, or exception message can become a secondary leakage path unless it receives the same filtering.

OWASP’s Logging Cheat Sheet similarly recommends excluding or masking access tokens, authentication passwords, sensitive personal data, and other secrets from logs. Page analytics should follow the same discipline.

Test route classification like production code

A rule that works for three hand-picked URLs can still fail on locales, old routes, Back navigation, account switches, or a broad regex introduced six months later. Keep a fixture set in version control or an equivalent maintained test system, and run it whenever rules, router behavior, or product structure change.

Minimum URL grouping and navigation test cases
Case Example Expected assertion
Exact route /settings/billing The exact Billing rule wins and no broad Settings rule overrides it.
Numeric ID /reports/451 The ID becomes :report_id; Report details is assigned.
UUID /projects/550e8400-e29b-41d4-a716-446655440000 The documented project parameter is normalized without changing the surrounding route.
Slug /teams/design A maintained route definition decides whether design is a team identifier or a meaningful static value; no generic guess is accepted silently.
Locale prefix /fr/reports/451 The same normalized page and grouped page are used as for the default locale; locale is handled separately if approved.
Query parameter /reports/451?tab=history&page=2 The report route stays stable; an allowlisted tab is retained as state and pagination is ignored.
Hash route /#/projects/abc123/tasks/789 The application’s hash-routing convention is parsed intentionally and produces one logical page view.
Nested route /companies/128/reports/451/edit Company and report IDs are normalized while the stable edit action maps to Report builder.
SPA navigation Initial load → pushState → Back → replaceState redirect Each committed logical navigation is counted once; renders and title updates do not create extra page views.
Overlapping rule /settings/api-keys The preview reports all matches and the specific high-priority API keys rule wins deterministically.
Missing match /labs/new-surface The route enters a monitored unclassified fallback without being discarded or guessed into an unrelated page.
Sensitive value /invite/accept?token=EXAMPLE_TOKEN The token is absent from stored routes, previews, logs, event properties, and snapshots.
Route rename /reports/451/analytics/reports/451 Both routes map to the same stable grouped-page ID when the product meaning is unchanged, with the taxonomy change documented.
Account switch /workspaces/atlas/reports/451/workspaces/beacon/reports/883 The grouped page remains Report details while company identity updates correctly and no prior account context leaks into the new page view.

Provide a preview before activation

A useful rule-preview interface should show:

  • the privacy-safe sample URL;
  • the winning matched rule and any losing matches;
  • the normalized raw page;
  • the grouped page or feature;
  • the product area;
  • priority or regex conflicts;
  • unmatched examples and the fallback result;
  • the current and proposed classification side by side when editing a live rule.

After activation, monitor the rate of unclassified pages, overlapping matches, normalized-route cardinality, sudden appearance of new routes, and privacy-filter detections. A jump in any of these can indicate a product release, broken router metadata, an overly broad rule, or unsafe input.

Common URL grouping mistakes

Frequent mistakes and safer alternatives
Mistake Why it fails Better approach
Tracking every raw URL as a different page Record IDs create false pages and fragment adoption and trends. Keep privacy-safe evidence, then classify it into normalized and grouped levels.
Replacing every variable-looking segment Stable product meaning such as Billing, History, or Getting started can disappear. Prefer explicit route metadata and maintain semantic allowlists.
Removing all query parameters without review Meaningful tab, workflow, or module state may be lost. Classify parameters by analytical meaning and retain only reviewed, constrained state.
Retaining sensitive parameters Tokens, emails, search text, and customer values can spread into analytics and logs. Filter before persistence and default to a query allowlist.
Using page titles as stable identity Titles are localized, dynamic, personalized, and often update after load. Use durable route and grouped-page IDs; treat titles as display labels.
Letting a broad regex override a specific rule Distinct product pages collapse into a generic group without an obvious error. Anchor patterns, assign priorities, and surface all matches in preview.
Changing rule order without tests The same URL can receive a new classification even though no product behavior changed. Version rule precedence and run fixtures before deployment.
Counting SPA route changes twice Automatic history tracking and manual router calls can both emit a page view. Choose one primary navigation source and deduplicate by committed navigation.
Failing to capture SPA navigation The initial load is recorded, but later product pages disappear from analytics. Use the supported router lifecycle and test Back, Forward, redirects, and hash routes.
Using navigation labels as permanent grouped-page IDs Copy edits, localization, and information-architecture changes break trends. Keep a stable internal ID and a separately editable display label.
Silently reclassifying historical data Dashboards change with no explanation, weakening trust and reproducibility. Version rules, document material changes, and define the historical policy.
Deleting all raw evidence Analysts cannot debug a rule, investigate a visit, or explain a surprising aggregate. Retain the minimum privacy-safe evidence needed, with restricted access and intentional retention.
Accepting AI suggestions without review A plausible name can conceal an incorrect product grouping or over-normalization. Require samples, tests, rationale, approval, versioning, and rollback.
Treating unclassified pages as ingestion errors New or uncertain routes are lost, and teams are pushed toward aggressive guessing. Use a monitored fallback queue with privacy-safe examples and clear ownership.

How Hymetry connects raw pages, grouped pages, and product areas

Hymetry organizes B2B product behavior around Pages, Companies, Users, and Visits. Within Pages, normalized raw pages preserve detailed route evidence, grouped pages represent meaningful pages, features, or workflows, and product areas provide the higher-level product structure.

In Hymetry, a capitalized Visit is the session-level evidence layer. A page visit is the continuous period spent on one page within that session. Keeping those terms separate prevents a grouped-page metric from being confused with a session count.

This separation lets a product team use a stable grouped page such as Report details for account adoption, engagement, trends, and flows even when every company and report has a different URL. The same team can still inspect the underlying normalized route and follow the signal into the companies and users involved, then review the relevant visit when session evidence is needed.

The investigation path can move in either direction:

  • A grouped page with declining reach can lead to affected companies, the users inside those accounts, and the visits behind the change.
  • A company with narrow adoption can lead to missing grouped pages and product areas, then to the users and visits that explain what was actually used.
  • A visit can be interpreted in the context of the grouped pages, product areas, user, and company connected to it.

Grouping alone does not identify meaningful product adoption. A page visit can prove that a company reached a surface; it may not prove that the team completed a report, configured an integration, invited another user, or repeated a workflow successfully. A sound product analytics instrumentation plan should pair stable page identity with the actions, repetition, engaged time, or workflow outcomes needed for the decision.

For broader interpretation, see the guides to product-area adoption, page views, Visits, sessions, and engaged time, and B2B product analytics. Technical teams evaluating self-managed deployment can also inspect the Hymetry open-source repository.

Frequently asked questions

Should every dynamic URL segment become a placeholder?

No. Replace a segment when it identifies one instance of a resource and the surrounding route carries the product meaning. Keep stable semantic segments such as billing, permissions, or getting-started when those distinctions matter. Framework route metadata and maintained rules are more reliable than guessing from the segment’s shape.

Should product analytics remove every query parameter?

No. Tracking, pagination, cache-busting, and temporary state usually should not affect page identity. A selected tab, report mode, workflow step, or module may be useful as a safe property or grouped subpage. Tokens, email addresses, unrestricted search text, authentication values, and other sensitive data should be removed or protected before storage.

Is regex page grouping enough?

Regex rules are useful for legacy routes and fallbacks, but application route names or framework route templates are usually more reliable because they already identify dynamic parameters. Regex rules need anchoring, explicit priority, overlap detection, representative tests, and version history.

How should a single-page application record page views?

Record one page view for each committed logical navigation, including the initial route and client-side route changes. Prefer the router’s supported navigation lifecycle, test pushState, replaceState, Back and Forward navigation, and avoid running both automatic and manual tracking for the same transition unless deduplication is explicit.

Should the raw URL be preserved?

Preserve only the minimum privacy-safe route evidence needed for investigation, QA, and reclassification. Remove sensitive values before persistence where possible, restrict access, and set intentional retention. A stored “raw” route should not contain a token simply because it was present in the browser.

What should happen when a grouping rule changes?

Choose and document a historical policy. Options include applying the current taxonomy retroactively, using effective-dated rules, materializing the original classification, reprocessing retained evidence, or preserving original and current classifications side by side. Material changes should record their rationale, affected routes, version, and impact on trends.

Should a modal, drawer, or tab count as a page?

Only when it behaves like a meaningful, addressable product surface: it represents a distinct task, participates in navigation or Back behavior, and supports adoption or flow questions. Minor interface state is usually clearer as an event or safe page property.

Does a grouped-page visit prove feature adoption?

No. It proves that the company or user reached the classified surface under the measurement rules. Meaningful adoption may also require a key action, completion, repeated use, engaged time, breadth across users, or another product-specific outcome.

Sources

  1. WHATWG, “URL Standard.” https://url.spec.whatwg.org/
  2. Internet Engineering Task Force, RFC 3986, “Uniform Resource Identifier (URI): Generic Syntax.” https://datatracker.ietf.org/doc/html/rfc3986
  3. Internet Engineering Task Force, RFC 6570, “URI Template.” https://datatracker.ietf.org/doc/html/rfc6570
  4. WHATWG, HTML Living Standard, “The History interface.” https://html.spec.whatwg.org/multipage/nav-history-apis.html#the-history-interface
  5. MDN Web Docs, “Working with the History API.” https://developer.mozilla.org/en-US/docs/Web/API/History_API/Working_with_the_History_API
  6. MDN Web Docs, “Window: popstate event.” https://developer.mozilla.org/en-US/docs/Web/API/Window/popstate_event
  7. MDN Web Docs, “History: pushState() method.” https://developer.mozilla.org/en-US/docs/Web/API/History/pushState
  8. OpenTelemetry, “Semantic conventions for HTTP spans.” https://opentelemetry.io/docs/specs/semconv/http/http-spans/
  9. OpenTelemetry, “Semantic conventions for events.” https://opentelemetry.io/docs/specs/semconv/general/events/
  10. Google for Developers, “Measure pageviews.” https://developers.google.com/analytics/devguides/collection/ga4/views
  11. Google Analytics Help, “Enhanced measurement events.” https://support.google.com/analytics/answer/9216061?hl=en
  12. Google Analytics Help, “Best practices to avoid sending Personally Identifiable Information (PII).” https://support.google.com/analytics/answer/6366371?hl=en
  13. Google Analytics Help, “Data redaction.” https://support.google.com/analytics/answer/13544947?hl=en
  14. Twilio Segment, “Spec: Page.” https://www.twilio.com/docs/segment/connections/spec/page
  15. Next.js, “Dynamic Route Segments.” https://nextjs.org/docs/app/api-reference/file-conventions/dynamic-routes
  16. React Router, “Routing.” https://reactrouter.com/start/framework/routing
  17. Vue Router, “Dynamic Route Matching with Params.” https://router.vuejs.org/guide/essentials/dynamic-matching.html
  18. SvelteKit, “Routing.” https://svelte.dev/docs/kit/routing
  19. Django documentation, “URL dispatcher.” https://docs.djangoproject.com/en/6.0/topics/http/urls/
  20. Microsoft Learn, “Routing in ASP.NET Core.” https://learn.microsoft.com/en-us/aspnet/core/fundamentals/routing?view=aspnetcore-10.0
  21. OWASP, “Information exposure through query strings in URL.” https://owasp.org/www-community/vulnerabilities/Information_exposure_through_query_strings_in_url
  22. OWASP Cheat Sheet Series, “Logging Cheat Sheet.” https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html
  23. OWASP Cheat Sheet Series, “REST Security Cheat Sheet.” https://cheatsheetseries.owasp.org/cheatsheets/REST_Security_Cheat_Sheet.html
  24. Hymetry, “Pages Analytics.” https://www.hymetry.com/product/pages/
  25. Hymetry, “Companies: Account Intelligence.” https://www.hymetry.com/product/companies/
  26. Hymetry, “User Intelligence for B2B SaaS.” https://www.hymetry.com/product/users/
  27. Hymetry, “Session Visits & Replay.” https://www.hymetry.com/product/visits/
  28. Hymetry, “Privacy Controls.” https://www.hymetry.com/product/privacy-controls/
  29. Hymetry, “Pages — Demo project.” https://app.hymetry.com/projects/demo/pages/
  30. Hymetry, open-source repository. https://github.com/Hymetry/Hymetry

About Hymetry

Hymetry is account-centric product intelligence for B2B SaaS. It helps teams understand how customer companies and the users inside them adopt and use their product.