Skip to content

Add posthog analytics#56

Draft
yrjanaff wants to merge 3 commits intomainfrom
posthog
Draft

Add posthog analytics#56
yrjanaff wants to merge 3 commits intomainfrom
posthog

Conversation

@yrjanaff
Copy link

  • Wrap application in ConsentProvider in src/index.js, to ensure the user has consented before analytics is initialized.
  • Add tracking for key user interactions:
    • Search performed (search_performed)
    • Metadata view (metadata_detail_viewed)
    • Search result clicks (search_result_clicked)
    • Service URL copied (service_url_copied)
    • Download interactions (download_link_clicked, download_added_to_basket)
    • Application button clicks (application_link_clicked)
    • Map interactions (map_item_added, map_item_removed)
    • Facet filtering (facet_filter_applied)

- Wrap application in `ConsentProvider` in `src/index.js`, to ensure the user has consented before analytics is initialized.
- Add tracking for key user interactions:
  - Search performed (`search_performed`)
  - Metadata view (`metadata_detail_viewed`)
  - Search result clicks (`search_result_clicked`)
  - Service URL copied (`service_url_copied`)
  - Download interactions (`download_link_clicked`, `download_added_to_basket`)
  - Application button clicks (`application_link_clicked`)
  - Map interactions (`map_item_added`, `map_item_removed`)
  - Facet filtering (`facet_filter_applied`)
@yrjanaff yrjanaff changed the base branch from master to main March 20, 2026 08:47
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces PostHog analytics to the React app, with consent-aware initialization and a set of event captures for key user interactions.

Changes:

  • Added a ConsentProvider wrapper at app bootstrap to manage consent state and initialize/configure PostHog.
  • Implemented PostHog event tracking across search, metadata views, result clicks, copy/download actions, application links, map interactions, and facet filtering.
  • Added PostHog dependencies and environment variables for PostHog key/host.

Reviewed changes

Copilot reviewed 14 out of 15 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
yarn.lock Adds PostHog (and transitive) dependencies to the lockfile.
package.json Adds @posthog/react and posthog-js dependencies.
default.env Adds REACT_APP_POSTHOG_KEY and REACT_APP_POSTHOG_HOST placeholders.
.nvmrc Updates local Node version to v24.
src/utils/consentContext.js Introduces consent context/provider and PostHog init + opt-in/out behavior.
src/index.js Wraps <App /> with <ConsentProvider />.
src/components/routes/OidcCallback.js Captures a login event and captures exceptions via PostHog on callback failures.
src/components/routes/Metadata.js Captures metadata_detail_viewed when metadata page view tag is pushed.
src/components/routes/Home.js Captures search_performed with search string, counts, and active filters.
src/components/partials/SearchResults/MetadataSearchResult.js Captures result click and service URL copy events.
src/components/partials/SearchResults.js Captures “show more results” click events.
src/components/partials/FacetFilter/Facet.js Captures facet filter applied events including active filters.
src/components/partials/Buttons/MapButton.js Captures map add/remove events.
src/components/partials/Buttons/DownloadButton.js Captures download link click and “added to basket” events.
src/components/partials/Buttons/ApplicationButton.js Captures application link click events.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 17 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

navigate(autoRedirectPath);
} catch (error) {
console.error("Sign-in response error:", error);
posthog?.captureException(error);
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

posthog?.captureException(error) can still throw if captureException is undefined on the PostHog client (optional chaining here only guards posthog, not the method). Use optional chaining on the method call (or fall back to capture) to avoid a runtime error during the login callback error path.

Suggested change
posthog?.captureException(error);
posthog?.captureException?.(error);

Copilot uses AI. Check for mistakes.
Comment on lines +145 to +156
const selectedFacets = props?.searchData?.selectedFacets || {};
const activeFilters = getActiveFiltersFromSelectedFacets(selectedFacets);

posthog?.capture("facet_filter_applied", {
facet_field: props.facetField,
facet_field_name: props.facetFieldNameTranslated,
facet_name: props.facet.Name,
facet_name_translated: props.facet.NameTranslated,
facet_count: props.facet.Count,
action: checked ? "remove" : "add",
active_filters: activeFilters,
});
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The facet_filter_applied event is using active_filters derived from the current selectedFacets in props, but the click is about to add/remove the facet via navigation. This means the tracked active_filters will be stale (missing the newly added facet or still including the removed one). Consider computing the next selected facets (add/remove the clicked facet) before capturing, or capturing in a place that runs after searchData.selectedFacets has updated.

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +39
export const getActiveFiltersFromSelectedFacets = (selectedFacets = {}) => {
const activeFilters = [];

const flattenFacets = (facets, fieldName) => {
Object.values(facets || {}).forEach((facet) => {
activeFilters.push(`${fieldName}: ${facet.NameTranslated || facet.Name}`);

if (facet.facets && Object.keys(facet.facets).length > 0) {
flattenFacets(facet.facets, fieldName);
}
});
};

Object.keys(selectedFacets || {}).forEach((fieldKey) => {
if (selectedFacets[fieldKey]?.facets) {
flattenFacets(selectedFacets[fieldKey].facets, fieldKey);
}
});

return activeFilters;
};
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New helper getActiveFiltersFromSelectedFacets is now used for analytics payloads, but there are no unit tests covering its output (including nested facet structures). Since this module already has Jest coverage, please add tests for this function (e.g., flat facets, nested facets, and translated names).

Copilot uses AI. Check for mistakes.
@@ -1 +1 @@
v12.13.1
v24 No newline at end of file
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bumping .nvmrc to Node v24 is likely incompatible with the current tooling stack (react-scripts@5.0.1 / react-app-rewired), and may break local development and CI installs/builds. Please either keep the Node version aligned with what the toolchain supports, or update the build tooling to versions that explicitly support Node 24 and verify in CI.

Suggested change
v24
v18

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants