Scout — Full Product Context → feature documentation

AllTrails integration

An 'Open <trail> in AllTrails' row under the Trails list on a park's Explore tab and a forest's Nature tab. Built in May 2026, switched off behind alltrails_integration the same month, and still off: the flag exists only in the app, the server never serves it, and no admin control can turn it on, so no user can see the button today.

Summary

On a patch's detail screen, parks (parkData) and national forests (forestData) list their trails with a difficulty and a length. This feature adds, under that list, one tappable row per trail, "Open <trail name> in AllTrails", that tries to open the AllTrails app with a search for the trail's name and falls back to an AllTrails web search. That is the whole feature: a name search handed to another app.

It is built and switched off. The alltrails_integration flag defaults to false and its own description says "Currently broken — keep off until the deep link / fallback flow is fixed" (mobile/src/config/feature-flags.ts:39-44). Nobody outside a development build or an admin's own device can see the row.

Status

Built, flag pinned off, unreachable by users.

User-facing surfaces

None today. If the flag were on, the row would appear in two places:

Both tabs are part of the new patch detail screen's type-tab set (tabs/types/dispatch.ts:21-26, tabs/types/index.ts:75, :78). The previous screen (new_patch_detail_screen off) keeps only the Battle type tab (patch-type-data.ts:79-83), so it would never show these rows at all.

A third copy lives in the Scout.* component library for the DEV Library screen (mobile/src/scout/patch/types/ParkTypeTabV2.tsx, ForestTypeTabV2.tsx; a LinkRow demo at mobile/src/scout/catalog.tsx:1979 with a no-op press). That is a design catalogue behind Drawer → DEV, not a user surface.

How it works

  1. Data. A park or forest patch carries trails: Array<{ name, difficulty, length }> in its parkData / forestData JSON (mobile/src/domain/types.ts:35-39, :128, :146; backend/prisma/schema.prisma:189, :191). The shape is produced by the enrichment script's per-type schema (backend/scripts/patch-enrich.ts:60-69, :84-93). There is no AllTrails id, URL or slug anywhere in the data, the schema or the backend (no match for "alltrails" under backend/).
  2. Gate. ParkBody / ForestBody read isEnabled('alltrails_integration') from useFeatureFlags() (ParkTypeTabV2.tsx:52-53, ForestTypeTabV2.tsx:44-45) and render the rows only when true (:98-100, :77-87). The trails list itself renders regardless.
  3. Tap. openAllTrails(trailName) URL-encodes the name and calls Linking.openURL('alltrails://search?q=<name>'); if that rejects it tries https://www.alltrails.com/search?q=<name>; if that rejects too it gives up silently ("No browser/app available — silently give up. Nothing actionable.", ParkTypeTabV2.tsx:32-43, ForestTypeTabV2.tsx:24-35). Both files carry the same function; nothing is shared.
  4. Nothing comes back. No result is read, nothing is stored, no analytics event fires.

Data model

None of its own. Reads Trail.name from patches.park_data / patches.forest_data (schema.prisma:189, :191). No table, column or migration mentions AllTrails.

API surface

None. No backend endpoint, no flag row, no server-side code.

Key files

Configuration and flags

Flag Registry Default Prod Effect
alltrails_integration mobile only (feature-flags.ts:39) false not served, so false Shows the "Open in AllTrails" rows under Trails on the Explore and Nature tabs

There is no backend row to create: the admin page is generated from the backend registry, and adding the key there would be a code change and a deploy, not a toggle (feature-flag-definitions.ts:1-7, feature-flags-api.controller.ts:104-110).

Edge cases and known limits

What this feature does NOT do

Tests that cover it

None. No screen test, hook test, Maestro flow or unit test references alltrails_integration, trail-alltrails- or openAllTrails (searched mobile/screen-tests, mobile/hook-tests, mobile/src/**/__tests__, mobile/maestro). The feature's off state is covered only indirectly: the type-tab tests that exercise ParkTypeTabV2 with the flag at its default never render the rows.

Open questions