Skip to content

feat: Surveys 2.0 - #168

Merged
boehlerlukas merged 21 commits into
masterfrom
feat/surveys-v2
Oct 8, 2026
Merged

boehlerlukas merged 21 commits into
masterfrom
feat/surveys-v2

Conversation

@boehlerlukas

@boehlerlukas boehlerlukas commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Surveys 2.0: showSurvey options, survey containers and embed

This is the web SDK side of Surveys 2.0. It adds:

  • new survey containers: a card popover that becomes a phone bottom sheet, a full-viewport Typeform-style screen, and an inline page;
  • an options form of Gleap.showSurvey;
  • survey lifecycle events and optional analytics forwarding;
  • a small standalone survey-embed.js.

Old format strings keep working, and a legacy (not yet migrated) survey switches the frame back to the old look when the Messenger-App reports survey-legacy.

Head at time of writing: a686d32 (18 commits). Program overview, master rollout and risks: https://github.com/GleapSDK/Server/pull/2011. Contract: SURVEYS_V2_SPEC.md §7, §13. Design: https://claude.ai/artifact/AnPuqYBjvmVxxgxHozHfi1

Scope

API

  • Gleap.showSurvey(id, formatOrOptions). Options: { format: 'card'|'full'|'page', fields, personalToken, container, resume }.
    • Legacy 'survey' maps to card; 'survey_full' and 'survey_web' map to full.
    • A call made before the session is ready now waits for it.
  • Triggered surveys (ping/WebSocket actions) pass resume, resumeData and outboundAction to the Messenger-App, for resume reminders.
  • New events, typed in index.d.ts: survey-shown, survey-answered, survey-completed, survey-closed, survey-step-viewed. outbound-sent and feedback-sent keep firing. For migrated surveys they carry the legacy field names (handled by the Messenger and Server).
  • Surveys 2.0 completions track outbound-<id>-submitted like legacy surveys (9e3f35a).

Containers (UI.js, GleapFrameManager.js)

  • Card:
    • a 348px corner popover with an enter animation;
    • on phones, a floating bottom sheet that stays above the on-screen keyboard and reports sheet-viewport to the messenger, so the header and Next stay pinned;
    • the launcher steps aside while a survey is open.
  • Full screen covers the whole viewport (no 700px cap and no centred 640px card), and takes keyboard focus when shown by a trigger.
  • Page renders inline in container (or body), grows with the content, scrolls the frame's top into view on step change, and forwards keys typed on the host page.
  • Corners (sharp/rounded/pill) and the light/dark surface follow the Messenger's survey-theme message. An old Messenger sends no message, so the default is rounded.
  • Card and page appear only once their height is known, and reduced motion is respected.

Analytics forwarding (opt-in per survey or project, off by default)

  • gleap_survey_shown|step_viewed|answered|completed { survey_id, survey_name, step_index, block_key } go to dataLayer, gtag('event') and fbq('trackCustom'). Answer values are never sent.

Embed

  • survey-embed.js (about 3 KB): <div data-gleap-survey="ID" data-api-key="KEY" data-mode="inline|popup|tab"> loads the SDK on demand. Embeds are a paid channel: on Free the Server refuses embed answers.

Performance (a686d32)

  • The visualViewport scroll/resize handler runs at most once per animation frame, and returns at once unless a card sheet is lifted.
  • The SDK adds no requests per page load. Survey checks happen only on showSurvey or triggers, and listeners are registered once.

CHANGELOG

  • An "Unreleased" entry is added. The version bump and build/ ship with the release commit; build output is not committed here.

Risk and safety

  • Compatibility:
    • Old pinned SDKs still render 2.0 surveys: card in the old container, full screen in the old centred 640px frame. Their callbacks are relayed.
    • Old pinned SDKs don't track outbound-<id>-submitted for 2.0 completions; 3 live EU rules depend on it.
    • CDN latest users get everything automatically.
  • The survey page depends on this release: HelpCenterApp#106 calls showSurvey(id, { format: 'page', … }) from sdk.gleap.io/latest.
  • Tests: npm test 514/514 and npx webpack, re-run on 2026-10-07 at a686d32 (the branch is level with master, nothing to merge). The build output (build/, published/) stays uncommitted, as for every feature PR here; the local stack serves a copy. The container and UI code gets no new unit tests (workspace rule).
  • Verified locally (SDK test page, CDP capture):
    • card, full and page end to end;
    • the iPhone 13 viewport sheet with the keyboard;
    • legacy chrome on survey-legacy;
    • showSurvey(id, 'survey') on a migrated survey;
    • the request counts (0 extra per page load).
  • Not verified: real iOS Safari and Android Chrome keyboards on devices; GA4/GTM/Meta Pixel against real accounts.

Rollout (this repo)

Release after Server#2011, Messenger-App#238 and Frontend#2221 are live (at least EU). Release to npm and the CDN (latest), and set the version in the CHANGELOG. Then:

  1. Put that version into gleap-api-docs#57 (documentation/javascript/surveys.mdx).
  2. Deploy HelpCenterApp#106.

Everything else is in the master checklist at https://github.com/GleapSDK/Server/pull/2011.

Surveys 2.0 PRs

🤖 Generated with Claude Code

boehlerlukas and others added 18 commits October 6, 2026 21:35
…ort, inline page)

Card: 348px corner popover with 18px radius and enter animation; on phones a
bottom sheet with handle, scrim and safe-area inset. Full: covers the viewport,
the messenger draws the background and close button. Page: inline frame in a
host container that follows the survey's height. Card and page surveys stay
invisible until the messenger reports their height. Safe-area insets are sent
to the messenger (survey-safe-area). Reduced motion respected.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ner, resume)

Legacy format strings keep working. start-survey keeps `format` as the
messenger app mode (survey | survey_full | survey_web | survey_page) and adds
surveyFormat, fields, personalToken, resume, outboundAction and safeArea.
showSurvey before the session is ready opens once it is; an inline survey page
is never replaced by a triggered survey.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Handles the messenger's survey-legacy (back to the pre-2.0 card / centred
full-screen chrome) and survey-shown / survey-answered / survey-completed /
survey-closed, exposed as SDK events (typed in index.d.ts). survey-shown now
comes from the messenger only; outbound-sent stays on notify-event.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…takes keyboard focus when shown by a trigger

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Inset 8px from the edges and above the home indicator, 32/40px corners,
layered shadow; legacy card surveys get the same floating panel.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Relays the messenger's survey-step-viewed message as an SDK event. When
the survey (data.forward) or the project (flowConfig
surveyAnalyticsForwarding) enables it, survey shown/step viewed/answered/
completed are pushed as gleap_survey_* events to window.dataLayer, gtag and
fbq with survey_id, survey_name, step_index and block_key only (no answer
values). Off by default; every sink optional and guarded.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…eta Pixel

Wires GleapSurveyAnalyticsForwarder into the messenger message handler and
types the survey-step-viewed event.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rd (sheet-viewport) so the header and Next stay pinned

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y surveys

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-theme)

Sharp 10px card / 14px sheet, Pill 32px card / 40-46px sheet; rounded card 24px
(matches the editor). Messengers that never send survey-theme keep the rounded outline.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…er steps aside while a survey is open

- survey-theme surface + dark: the phone sheet (handle strip included) and the
  card's underlay use the survey's surface, the handle its light/dark
- the survey page frame takes the survey's color-scheme so it stays
  transparent on any host backdrop
- the launcher hides while a survey is open (a pill or sharp card showed it
  peeking out behind its corner)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… moves to a new step

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…oes nothing unless a card survey sheet is lifted

visualViewport scroll/resize fire many times a second while any page with the SDK scrolls; every event touched the frame container's styles even with no survey on screen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
boehlerlukas and others added 3 commits October 8, 2026 10:22
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@boehlerlukas
boehlerlukas merged commit da28111 into master Oct 8, 2026
1 check passed
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.

1 participant