Skip to content

Redesign article feedback section for product-aware routing and labels #7095

@jstirnaman

Description

@jstirnaman

Context

#7090 fixed #7089 (wrong feedback button target for InfluxDB 3 Enterprise) with a minimal, behavior-preserving refactor: extract product issue URLs into data/products.yml (product_issue_url field) so layouts/partials/article/feedback.html reads from config instead of computing URLs with conditional logic.

That fix is ready to merge, but subsequent discussion on the PR surfaced a more nuanced routing policy than the original template expressed. The current product_issue_url field is too coarse for what real user needs look like, and the hardcoded Submit issue button label doesn't fit every destination.

Correct per-product routing

Per product characteristics (has-public-repo × support-contract-required), feedback button destinations should be:

Product Repo? Contract? Destination State after #7090
InfluxDB 3 Core influxdb free GitHub influxdata/influxdb ✅ correct
InfluxDB 3 Enterprise optional Discord (preferred channel per feedback template) Support ❌
InfluxDB 3 Explorer optional Discord (preferred channel) GitHub influxdata/influxdb
InfluxDB 3 Cloud Serverless optional Slack (preferred channel for non-v3-monolith) Support ❌
InfluxDB 3 Cloud Dedicated required Support site ✅ correct
InfluxDB 3 Clustered required Support site ✅ correct
InfluxDB OSS v1/v2 influxdb free GitHub influxdata/influxdb ✅ correct
InfluxDB Cloud (TSM) optional Slack (preferred channel) Support ❌
Telegraf telegraf optional GitHub influxdata/telegraf ✅ correct
Chronograf chronograf free GitHub influxdata/chronograf ✅ correct
Kapacitor kapacitor free GitHub influxdata/kapacitor ✅ correct
InfluxDB Enterprise v1 required Support site ✅ correct
Flux flux free GitHub influxdata/flux ✅ correct

Incorrect after #7090: v3 Enterprise, v3 Explorer, Cloud Serverless, Cloud (TSM) — 4 products.

"Preferred channel" refers to the existing conditional in layouts/partials/article/feedback.html:

{{ if and (eq $product "influxdb3") (or (eq $version "core") (eq $version "enterprise") (eq $version "explorer")) }}
  Discord (Preferred)
{{ else }}
  Slack (Preferred)
{{ end }}

So for v3 monolith products (Enterprise, Explorer) Discord is preferred; for v3 distributed + Cloud (TSM), Slack is preferred.

Button label mismatch

The third feedback button hardcodes Submit {{ $productName }} issue. This label fits GitHub and Support destinations, but not Discord, Slack, or Community forum — users don't "submit issues" on Discord, they ask questions. #7090 preserves this label and only changes the URL.

Product identification bug — .RelPermalink vs .File.Path

Added during PR review of #7090: the Enterprise "Submit issue" button on the PR preview was observed to link to the preview page URL itself instead of the Support site.

Root cause

The feedback template identifies the current product by parsing .RelPermalink:

{{ $productPathData := findRE "[^/]+.*?" .RelPermalink }}
{{ $product := index $productPathData 0 }}
{{ $version := index $productPathData 1 }}

Hugo's .RelPermalink returns the page URL path relative to the baseURL's host, so it includes any path prefix from baseURL. The PR preview builds with:

--baseURL https://influxdata.github.io/docs-v2/pr-preview/pr-7090/

For content/influxdb3/enterprise/get-started/_index.md, this makes .RelPermalink = /docs-v2/pr-preview/pr-7090/influxdb3/enterprise/get-started/. The findRE then assigns:

  • $product = "docs-v2" (wrong)
  • $version = "pr-preview" (wrong)
  • $productKey = "docs-v2" → lookup in data/products.yml returns nil
  • $productIssueUrl = "" → empty href="" → browser resolves to current page URL

This is pre-existing, not a regression from #7090

The pre-#7090 template used the same findRE "[^/]+.*?" .RelPermalink pattern. In the pre-refactor code, $product = "docs-v2" flowed into $productNamespace and produced https://github.com/influxdata/docs-v2/issues/new/choose/ — a wrong-but-existing URL. The refactor didn't introduce the parsing bug; it changed the failure mode from "wrong URL that happens to resolve" to "empty href that falls back to current page", making the latent bug visibly manifest.

Why the CI check didn't catch it

.github/workflows/pr-feedback-links.yml builds Hugo with the default baseURL (no subpath), so Layer 2 correctly identifies products and verifies hrefs. It never exercises the preview-baseURL code path.

Is there a reason to keep .RelPermalink?

Arguments for:

  1. Pages without .File — taxonomy/term pages, paginator pages, pages generated from data files. .File is nil on those; .File.Path errors. .RelPermalink always exists.
  2. Permalink/url frontmatter overrides.RelPermalink reflects the custom URL.
  3. Shared content via source: frontmatter — does .File.Path point to the consumer or the source? Answer: consumer. .File.Path = path of the .md file that declared source:. So shared content works identically with either approach.

Arguments against:

  1. Breaks on any non-root baseURL — observed on PR preview; would fire on any GH Pages subpath deployment, any branch-preview infrastructure, any tunnel that rewrites paths.
  2. Brittle regex. findRE "[^/]+.*?" is hard to reason about. The .*? is lazy and effectively matches empty — a single anchor is doing no real work. findRE "[^/]+" would be clearer with either path source.
  3. Inconsistent with the rest of the template. The pageGithubLink already uses .File.Path. Product detection should use the same signal.
  4. Harder to test. Layer 2 of the CI check runs Hugo with default baseURL and passes — the bug is invisible to the test unless we deliberately build with a subpath baseURL.

Verdict: no strong reason to keep .RelPermalink as primary source. The one concern (virtual pages without .File) is addressable with a guarded fallback:

{{ $path := "" }}
{{ if .File }}
  {{ $path = path.Dir .File.Path | string }}
{{ else }}
  {{ $path = strings.TrimPrefix site.BaseURL.Path .RelPermalink }}
{{ end }}
{{ $productPathData := findRE "[^/]+" $path }}
{{ $product := index $productPathData 0 }}
{{ $version := index $productPathData 1 }}

This:

  • Fixes the preview-baseURL bug class
  • Preserves behavior on virtual pages via baseURL-stripped .RelPermalink fallback
  • Uses .File.Path consistently with the edit-link logic elsewhere in the same partial
  • Replaces the brittle [^/]+.*? regex with a clean [^/]+

If investigation confirms the feedback partial is only rendered on content pages with .File, the fallback could be dropped entirely.

CI test gap

The current pr-feedback-links.yml only runs Hugo with default baseURL. To catch this bug class, the workflow should either:

  • Run Layer 2 a second time with --baseURL https://example.com/subpath/ and verify hrefs still resolve to the expected values; or
  • Add a dedicated smoke test that confirms every feedback button on a preview-style build has a non-empty href that doesn't end with the current page path.

Proposed redesign options

Option A — Add product_issue_label field to products.yml

influxdb3_enterprise:
  product_issue_url: https://discord.gg/9zaNCW2PRT
  product_issue_label: Ask on Discord

influxdb3_cloud_dedicated:
  product_issue_url: https://support.influxdata.com/s/
  product_issue_label: Contact InfluxData Support

influxdb3_core:
  product_issue_url: https://github.com/influxdata/influxdb/issues/new/choose/
  product_issue_label: Submit InfluxDB 3 Core issue

Template reads {{ $productData.product_issue_label }} with a fallback to Submit {{ $productName }} issue.

Option B — Hide the third button entirely for non-repo products

The community links (Discord, Slack, Community, Reddit) are already rendered in the support section above the button row. Duplicating them as a button adds no value. Products without a repo-or-Support destination would show only Edit this page + Submit docs issue, which is cleaner.

Option C — Collapse into product_help object with type discrimination

product_help:
  type: github        # or: support | discord | slack | community | hidden
  url: https://github.com/influxdata/influxdb/issues/new/choose/

Template branches on type for label, icon, and aria-label. Most structured but adds complexity.

Recommendation: Option A. Lowest churn, composable with existing product_issue_url, extends the data-driven pattern from #7090 without reintroducing conditional logic in the template.

Related cleanup worth bundling

  • Simplify the whole feedback section. The current block contains: a Yes/No helpfulness widget, a support-resource list (Discord/Slack/Community/Reddit/Support/trial email), and three action buttons (Edit / Submit docs issue / Submit product issue). That's at least 9 distinct CTAs. Most pages probably only need 2–3.
  • Switch product identification from .RelPermalink to .File.Path with a baseURL-stripped fallback (see the root-cause section above).
  • Remove the $supportBlacklist hardcoded slice (chronograf, kapacitor) — data-drivable via a show_support_contact: false field per product.
  • Data-drive the preferred-community-channel conditional — move to products.yml as preferred_community_channel: discord | slack instead of the inline template check.
  • Extend check-feedback-links.js Layer 2 to assert rendered button labels match product_issue_label once that field lands, and to run a second pass with a subpath baseURL to catch preview-style regressions.

Acceptance criteria

  • Every product with a content_path in data/products.yml routes to the correct destination per the table above
  • Button label matches destination type (no "Submit issue" on Discord/Slack/Community links)
  • layouts/partials/article/feedback.html contains no conditional URL or label logic (fully data-driven)
  • Product identification in feedback.html uses .File.Path (or equivalent baseURL-independent source) so preview-baseURL builds resolve correctly
  • .ci/scripts/check-feedback-links.js Layer 2 verifies button labels against product_issue_label
  • CI runs Layer 2 a second time with a subpath baseURL to catch .RelPermalink-style regressions
  • Feedback section reviewed for CTA overload — drop or consolidate redundant links
  • Visual regression check across one representative page per product, on production AND preview baseURLs

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:site-uiDocumentation site UI: templates, styles, JS/TS

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions