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.

Separate page levels before normalizing dynamic segments

A route such as /companies/128/reports/451?tab=history can produce one row per record, fragment adoption analysis, and expose unsafe values. The solution is not to discard the URL or collapse everything called Settings. Build a deterministic classification chain whose levels answer different questions.

Four page levels and their analytical jobs
LevelExampleQuestionUse
Privacy-safe observed route/companies/128/reports/451What safe route evidence arrived?Debugging, rule preview, Visit investigation
Normalized route/companies/:company_id/reports/:report_idWhich stable technical pattern matched?Route QA, change detection, path analysis
Grouped page/featureReport detailsWhich product surface did the user reach?Adoption, trends, flows, account comparison
Product areaReportingWhich broader capability contains it?Breadth and portfolio reporting

“Raw” should never mean every character the browser exposed. Filter tokens, email addresses, customer-entered names, confidential search terms, and other prohibited values before analytics persistence, rule-preview logs, errors, exports, or replay metadata. Retain only the most detailed evidence the organization has intentionally judged safe and necessary.

One URL, normalized segment by segment

The unsafe value is dropped at the boundary; the record IDs become named segments.

Observed

/companies 128 /reports 451 ?token=secret-value

Filtered

/companies 128 /reports 451 dropped before storage

Normalized

/companies :company_id /reports :report_id

Grouped page

Report details

Product area

Reporting
Useful page analytics keeps the evidence chain while removing unsafe values and collapsing record-specific routes into stable product entities.

Strong dynamic-segment clues include framework-declared parameters, database-style numeric IDs, UUIDs, ULIDs, hashes, timestamps, opaque tokens, and known tenant or object positions. Human-readable slugs are ambiguous: /teams/design may contain a team identifier, while /settings/design may be a stable product route. Locale, deployment prefix, API version, action suffix, and tenant subdomain can also carry deliberate meaning.

Use route position and application semantics, not shape alone. Normalize only the dynamic value, preserve stable action segments such as edit, and watch normalized-route cardinality. A sudden increase can reveal a missed identifier; a dramatic decrease can reveal an over-broad rule. The goal is a stable, useful taxonomy, not the smallest possible page count.

Detection heuristics and their failure modes

Numeric IDs, UUIDs, ULIDs, long hashes, and framework-declared parameters are strong candidates, but each can appear as a meaningful static value in a different route. Human-readable slugs are harder: a customer workspace, report name, locale, product module, and action can all look like ordinary words. Use surrounding segments, the matched router record, known object positions, and a fixture set before replacing them.

Do not normalize by global string replacement. An ID-like value can appear in a query, fragment, page title, or free-text value with different privacy and analytical treatment. Parse the URL with a standards-compliant implementation, preserve percent-encoding semantics, and avoid assuming parameter order or duplicate parameters are equivalent unless the application contract says so.

Monitor the number of distinct observed safe routes per normalized route, examples per rule, match rate by application version, and unclassified volume. Extremely high fan-in may be legitimate for record pages; unexpected changes after a release should trigger review. Keep representative positive, negative, boundary, and sensitive fixtures for every heuristic.

Prefer route contracts and track logical navigation

Modern routers already know which segments are parameters. Prefer an explicit application route name, matched router record, file-system route ID, or server endpoint template over inference from the final URL. Framework syntax differs, but all can map to one internal contract:

/companies/:companyId/reports/:reportId
/projects/[projectId]/tasks/[taskId]
/users/{user_id}/settings
{
  "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" }
}

This payload is conceptual, not a Hymetry API contract. The stable name/template identifies the route, the safe path supports evidence and QA, and reviewed state remains separate so it does not multiply route identity.

Classify query and fragment state by meaning

Do not apply one strip-or-keep rule to every parameter
CategoryExamplesTreatment
Usually irrelevant to page identityutm_*, click IDs, sort, page, cache valuesDrop from normalized URL; govern separately if needed
Potentially meaningful statetab, mode, step, moduleAllowlist constrained values as properties, subpages, or workflow steps
Sensitive or prohibitedTokens, authorization codes, email, customer IDs, names, unrestricted search textRemove before persistence and from every secondary log

For /reports/451?tab=history, the route can remain /reports/:report_id while tab=history becomes safe state. Create a separate grouped page only when History is a substantial task with its own adoption question. A token has no such option:

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

In a single-page application, a document may load once while logical routes change repeatedly. Account for initial load, router commits, history.pushState(), history.replaceState(), Back/Forward popstate, redirects, and hash routing where relevant. Calling pushState() or replaceState() does not itself fire popstate, so a listener limited to that event can miss forward navigation.

Choose one primary source and deduplicate notifications for the same committed navigation. Automatic history tracking plus manual router calls is a common duplicate source. Renders, title updates, data refreshes, and minor state changes are not new pages.

function onNavigationCommitted(navigation) {
  const safe = privacyFilter(navigation.url);
  const page = classifyPage({
    safeUrl: safe.url,
    routeName: navigation.routeName,
    routeTemplate: navigation.routeTemplate
  });

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

This is framework-neutral pseudocode. Use the router and analytics tool’s supported APIs. A URL-changing modal, drawer, or tab can be page-like if it is addressable, supports Back, represents a distinct task, and belongs in flow analysis. Lightweight confirmation UI is usually an event.

Design grouping rules as a versioned classification system

A grouping rule changes the analytical data model. Give it a stable rule ID, project/environment scope, match type and pattern, priority, normalized route, durable grouped-page ID, product-area ID, active status, source, owner, review state, timestamps, effective dates, and definition version. Keep stable IDs separate from editable labels.

A practical deterministic precedence
PrioritySourceExampleReason
1Application route name/metadatasettings.api_keysMost explicit product-owned identity
2Exact route/settings/billingSpecific maintained mapping
3Route template/reports/:report_id/editStable dynamic structure
4Anchored regex^/legacy/reports/[^/]+$Useful fallback when templates are unavailable
5Conservative fallbackUnclassified route bucketPreserves evidence without inventing meaning

Report all overlapping matches in preview, even when priority chooses a winner. Broad patterns can silently steal routes after a product release. Anchor regexes, avoid catastrophic expressions, and treat tie-breaking as a visible conflict. A conceptual rule can look like this:

{
  "rule_id": "page_rule_report_details",
  "match_type": "route_template",
  "match_pattern": "/companies/:company_id/reports/:report_id",
  "priority": 300,
  "normalized_route": "/companies/:company_id/reports/:report_id",
  "grouped_page_id": "report_details",
  "product_area_id": "reporting",
  "version": 3,
  "effective_from": "2026-08-04"
}

Twelve routes collapse into four product areas

One tile is one page view. Total width never changes — grouping relabels evidence, it does not lose it.

12 observed routes

••• ••• ••• ••• ••• ••• ••• ••• ••• ••• ••• •••

6 normalized routes

/companies/:id /reports/:id /edit /new /integrations/:p /settings/users

5 grouped pages

Company overview Report details Report builder Integration settings User management

4 product areas

Core accounts Reporting Integrations Administration

4 fictional companies · 7 visits · every tile still opens back to the visit that produced it.

The precise order varies by implementation, but specific, reviewable sources should normally win over broad inference.

AI can suggest ID-like segments, route names, or candidate groups, but cannot infer the intended taxonomy reliably from strings alone. Present suggestions with samples, frequency, proposed pattern, confidence explanation, and conflicts. A person who understands the product should approve the mapping and its historical effect.

Worked example: collapse dynamic routes without losing evidence

Representative route transformations
Safe observed routeNormalized routeGrouped pageAreaDecision
/companies/128/reports/companies/:company_id/reportsReports listReportingCompany ID normalized
/companies/128/reports/451/companies/:company_id/reports/:report_idReport detailsReportingBoth object IDs normalized
/companies/128/reports/451/edit/companies/:company_id/reports/:report_id/editReport builderReportingStable action preserved
/projects/550e8400-e29b-41d4-a716-446655440000/tasks/789/projects/:project_id/tasks/:task_idTask detailsProjectsUUID and numeric ID normalized
/settings/billingsameBilling settingsAdministrationStatic semantic route retained
/fr/reports/451?tab=history&page=2/reports/:report_idReport detailsReportingLocale separate; tab allowlisted; pagination dropped
/invite/acceptsameInvitation acceptanceAdministrationToken removed before this layer
/labs/new-surfaceunclassifiedUnclassifiedUnassignedMonitored fallback, no guess

Twelve record-specific observations can collapse into a much smaller set of stable routes and grouped pages while their visits remain countable and traceable. The normalized layer supports engineering QA; grouped pages support questions such as which accounts reached Report details; product areas support Reporting adoption breadth. Do not use a grouped-page visit as proof that the workflow completed.

The first rule that matches wins

Specific, reviewable sources are evaluated before broad inference.

Input/settings/api-keys

  1. 1 Application route name no match
  2. 2 Exact manual rule no match
  3. 3 Route template no match
  4. 4 Regex rule two rules match
  5. 5 Safe fallback not reached
  6. 6 Unclassified queue not reached

Tie-break at step 4

^/settings/api-keys$priority 500 · wins

^/settings/[^/]+$priority 100 · kept visible

API keys

Normalization changes classification, not the underlying visits. Teams gain stable adoption and flow analysis without losing the path back to source evidence.

Protect URL data and preserve historical comparability

URLs may expose authorization codes, reset tokens, emails, customer names, search text, document names, support details, file paths, or secrets. HTTPS protects transit; it does not prevent values appearing in browser history, referrers, proxy logs, analytics fields, or debugging systems. Filter at or before collection wherever possible.

Privacy controls

  • Default-deny query/fragment values and allowlist constrained state.
  • Keep identity in governed fields, not parsed route strings.
  • Apply the same filter to previews, logs, exports, replay metadata, and failures.
  • Restrict detailed evidence access and set intentional retention.
  • Test synthetic tokens, email-shaped values, encoded text, and tenant slugs.

History controls

  • Use stable grouped-page and rule IDs.
  • Record effective dates and approvals.
  • Preview affected observations before activation.
  • State whether history is preserved, reclassified, or shown both ways.
  • Annotate dashboards after a material split or merge.

A spelling correction can keep the same stable ID. Splitting generic Settings into Billing, Permissions, and API Keys changes analytical meaning. Choose deliberately among query-time classification, effective-dated rules, ingestion-time materialization, full reprocessing, or preserving both original and current classifications. No choice is universally correct; the report must disclose which view it uses.

Choose a historical policy for material taxonomy changes
StrategyBenefitTradeoffUse when
Classify at query timeHistory follows the current taxonomyPast dashboards can change without new behaviorSafe evidence is retained and reproducibility is less important
Effective-dated rulesReproduces the classification in forceOne feature can split across datesHistorical auditability is primary
Materialize at ingestionFast queries and explicit rule/version IDsCorrections require backfill or a second viewOperational stability matters
Full reprocessingOne consistent current viewCan be costly and rewrite reported numbersSource evidence and processing are available
Original plus currentSupports reproduction and current taxonomyMore storage and explanationBoth audit and evolving product models matter

For a migration, snapshot rule versions and affected route samples, run current and proposed classifiers side by side, compare page and area counts, inspect the largest movers, and approve the effective date. Publish a change note that says whether downstream funnels, adoption rates, and saved segments were backfilled. Keep old stable IDs as aliases when the product meaning is unchanged; create new IDs for real splits and merges.

Test route classification like production code

Maintain fixtures for exact, numeric-ID, UUID, slug, locale, query, fragment, nested, SPA, overlapping, missing, sensitive, renamed, and account-switch routes. Run them when router behavior, rules, or product taxonomy changes.

Minimum high-value QA cases
CaseInputAssertion
Overlapping rules/settings/api-keysAll matches shown; specific rule wins
SPA sequenceload → pushState → Back → redirectEach committed navigation counted once
Sensitive value/invite/accept?token=EXAMPLEToken absent from storage, preview, log, and event
Route rename/reports/451/analytics/reports/451Same grouped ID if meaning is unchanged
Account switchAtlas report → Beacon reportPage stable; account context changes without leakage
Unmatched route/labs/new-surfaceMonitored fallback preserves safe evidence

Before activation, preview the safe sample, winner, losing matches, normalized route, grouped page, area, conflicts, unmatched examples, and current-versus-proposed classification. After activation monitor unclassified rate, overlap rate, normalized-route cardinality, new routes, privacy-filter detections, page-view volume, and duplicate navigation IDs. Roll back a rule that causes unexpected taxonomy movement.

Route-change release checklist

  • Confirm the router emits the expected name/template in production builds and across locales.
  • Verify initial load, client navigation, redirects, Back/Forward, account switch, and authentication transitions.
  • Exercise query defaults, repeated parameters, encoded values, fragments, and trailing-slash policy.
  • Check that safe state remains bounded and that prohibited values disappear before all persistence paths.
  • Compare page-view counts with navigation IDs to detect both loss and duplication.
  • Review downstream grouped-page and product-area metrics for unexpected movement.
  • Assign the release, rule, taxonomy, and privacy owners and a rollback threshold.

Keep an unclassified queue small enough to review but never expose unsafe values in it. Sample the privacy-filtered pattern, frequency, first/last seen date, application version, and candidate route metadata. Repeated unknown routes may indicate a new feature; a one-off value may indicate noise or a failed filter. Classification should fail conservatively.

Reconcile product meaning after deployment

  • Product owners confirm that stable grouped-page IDs still describe customer tasks.
  • Engineers verify that route metadata survives code splitting and redirects.
  • Analysts check adoption and flow continuity.
  • Privacy owners review newly observed fields.
  • The team schedules periodic rule review because fixtures cannot reveal every new production route family or value.

When several applications share an analytics project, scope route contracts and rule precedence explicitly. The same /settings path can mean different products, environments, or embedded modules. Include application or project identity before classification instead of relying on broad prefixes that become ambiguous over time.

Common grouping mistakes
  • Keeping record IDs in analytical page names or replacing every variable-looking segment blindly.
  • Stripping every query parameter or retaining all of them.
  • Using labels, titles, or DOM text as stable page identity.
  • Listening only to full loads or popstate in an SPA.
  • Combining automatic and manual page views without deduplication.
  • Letting broad regexes win by configuration order.
  • Deleting unclassified routes or accepting AI suggestions without review.
  • Rewriting history silently and treating a page view as feature adoption.

Connect grouped pages to account evidence

Hymetry’s Pages surface connects stable product structure with Companies, Users, and Visits. Teams can inspect the Pages demo, privacy controls, and the open-source repository. The product taxonomy still requires deliberate naming, ownership, and validation.

Frequently asked questions

Should every dynamic URL segment become a placeholder?

No. Normalize values known to identify records or tenants; preserve stable segments that carry product meaning.

Should product analytics remove every query parameter?

No. Remove them by default, then allowlist constrained state only when it answers a defined question. Always remove secrets.

Is regex page grouping enough?

It can support legacy routes, but explicit route names/templates are safer. Regex rules need anchors, priority, conflict preview, fixtures, and owners.

How should an SPA record page views?

From one supported logical-navigation source, once per committed route, with initial load, redirects, Back/Forward, and deduplication tested.

Should the raw URL be preserved?

Preserve only intentionally retained privacy-safe evidence. Never keep a secret merely for debugging.

What should happen when a grouping rule changes?

Preview the effect, version and approve it, choose a historical policy, and annotate material breaks.

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

Only when it is addressable and represents a distinct task needed in adoption or flow analysis; otherwise use an event or state property.

Does a grouped-page visit prove feature adoption?

No. It supports reach or discovery. Adoption normally needs meaningful completion, state, recurrence, or another outcome signal.

Sources

Method note: Standards and framework documentation support route syntax and navigation behavior. Security guidance supports minimization. The internal taxonomy and worked routes remain implementation decisions.

Methodology and evidence limits

Route conventions differ across frameworks and versions. Validate the actual matched route and lifecycle in the application. Privacy controls described here reduce exposure but do not determine legal compliance. The conceptual payloads and pseudocode are not Hymetry API contracts.

Full source directory
Additional preserved references

These references supported the original detailed guide and remain available for claim verification and further reading.

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.