iOS_Logo_1024x1024-100.png
  • Home
  • Examples
    Native features
    SSR (getServerSideProps)SSGSSG using fallbackSSG using revalidateCatch-all routes
    Built-in features
    HostingStages & secretsCI/CDStatic i18nMonitoringAPI (Airtable)CSS-in-JSCookies consentAnalyticsIconsCSS AnimationsUI components libraryDocs siteMarkdown as JSX
    Built-in utilities
    I18nLink componentAirtableAsset componentHooksHOCsAPIErrors handlingBundle analysisSVG to ReactSecurity auditTracking useless re-renders
  • Documentation
  • Source code
  • Go to CMS

Built-in features

  • Hosting
  • Stages & secrets
  • CI/CD
  • Static i18n
  • Monitoring
  • API (Airtable)
  • CSS-in-JS
  • Cookies consent
  • Analytics
  • Icons
  • CSS Animations
  • UI components library
  • Docs site
  • Markdown as JSX

Previous section - Next sectionHome

Analytics examples, using Amplitude vendor

Before investing time in Amplitude, make sure to check their pricing and usage limits.
Amplitude is great for getting started but if you need more than what the free plan offers, then you better make sure you can afford it.
Amplitude provides a React component that makes it a breeze to work with, and we really love it.
It's much more comfortable from a developer standpoint that everything we've worked with by the past.

We only use Amplitude from the client, mostly because Amplitude didn't provide a nodejs compatible library until very recently.
Also, we prefer to perform all reporting on the client side, as it avoids issues with multiple events sent by mistake.

The app is configured in a way that all usual web-related analytics options are handled out the box.
It also comes with a shared configuration for all pages (see below) and user-session tracking.
Regarding GDPR concerns, the IP address is not processed/stored by any vendor (analytics data are anonymous). Several cookies are created on the device if the user hasn't opted out of tracking (through the Cookie Consent popup).


Shared analytics configuration

The below code is the shared configuration between all pages.
It initializes the whole thing, and automatically track app-wide data so that all event will contain those properties automatically.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 <AmplitudeProvider amplitudeInstance={amplitudeInstance} apiKey={process.env.NEXT_PUBLIC_AMPLITUDE_API_KEY} userId={userId} > <Amplitude eventProperties={{ app: { name: process.env.NEXT_PUBLIC_APP_NAME, release: process.env.NEXT_PUBLIC_APP_VERSION_RELEASE, stage: process.env.NEXT_PUBLIC_APP_STAGE, preset: process.env.NEXT_PUBLIC_NRN_PRESET, }, page: { url: location.href, path: location.pathname, origin: location.origin, name: null, // XXX Will be set by the page (usually through its layout) }, customer: { ref: customerRef, }, lang: lang, locale: locale, iframe: isInIframe, iframeReferrer: iframeReferrer, }} /> </AmplitudeProvider> // ... elsewhere // See https://help.amplitude.com/hc/en-us/articles/115001361248#settings-configuration-options amplitudeInstance.init(process.env.NEXT_PUBLIC_AMPLITUDE_API_KEY, null, { userId, logLevel: process.env.NEXT_PUBLIC_APP_STAGE === 'production' ? 'DISABLE' : 'WARN', includeGclid: true, includeReferrer: true, // See https://help.amplitude.com/hc/en-us/articles/215131888#track-referrers includeUtm: true, // @ts-ignore XXX onError should be allowed, see https://github.com/DefinitelyTyped/DefinitelyTyped/issues/42005 onError: (error): void => { Sentry.captureException(error); console.error(error); // eslint-disable-line no-console }, sameSite: 'Strict', // 'Strict' | 'Lax' | 'None' - See https://web.dev/samesite-cookies-explained/ }); amplitudeInstance.setVersionName(process.env.NEXT_PUBLIC_APP_VERSION_RELEASE); // e.g: v1.0.0 // We're only doing this when detecting a new session, as it won't be executed multiple times for the same session anyway, and it avoids noise if (amplitudeInstance.isNewSession()) { // Store whether the visitor originally came from an iframe (and from where) const visitor: Identify = new amplitudeInstance.Identify(); // XXX Learn more about "setOnce" at https://github.com/amplitude/Amplitude-JavaScript/issues/223 visitor.setOnce('initial_lang', lang); // DA Helps figuring out if the initial language (auto-detected) is changed afterwards visitor.setOnce('initial_locale', locale); // DA This will help track down the users who discovered our platform because of an iframe visitor.setOnce('initial_iframe', isInIframe); visitor.setOnce('initial_iframeReferrer', iframeReferrer); // XXX We set all "must-have" properties here (instead of doing it in the "AmplitudeProvider", as userProperties), because react-amplitude will send the next "page-displayed" event BEFORE sending the $identify event visitor.setOnce('customer.ref', customerRef); visitor.setOnce('lang', lang); visitor.setOnce('locale', locale); visitor.setOnce('iframe', isInIframe); visitor.setOnce('iframeReferrer', iframeReferrer); amplitudeInstance.identify(visitor); // Send the new identify event to amplitude (updates user's identity) }

Events - Automated page views

Below is how we automatically track all page views (through the DemoLayout component):

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <Amplitude eventProperties={(inheritedProps): object => ({ // All app-wide properties are inherited and overloaded to track additional properties ...inheritedProps, page: { ...inheritedProps.page, name: pageName, }, })} > {/* The event is automatically sent upon component mount */} <LogOnMount eventType="page-displayed" /> </Amplitude>

Events - User interactions

Below is how we log events upon user interaction. (i.e: click)
When you click on the below button an event analytics-button-test-event is sent to Amplitude.
No data will be sent if you've opted-out of analytics tracking:

You can check the event details using Amplitude Instrumentation Explorer Chrome extension.



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <Amplitude> {({ logEvent }: { logEvent: LogEvent }): JSX.Element => ( <Button onClick={(): void => { // eslint-disable-next-line no-console console.log('Button click'); logEvent(AMPLITUDE_EVENTS.ANALYTIC_BUTTON_TEST_EVENT, { action: AMPLITUDE_ACTIONS.CLICK, }); }} > Click me </Button> )} </Amplitude>

Your Amplitude Device ID

This is only informational, your activity on this website is being tracked for analytics purposes and demonstration on how to perform analytics with Next.js and Amplitude (this uses userSessionContext store provider).


1 2 3 4 5 6 7 8 9 10 11 12 13 14 <DisplayOnBrowserMount // When using SSR, we want to render the deviceId immediately because we have access to it through server cookies // When using SSG, we need to wait for the browser render because we don't have access to the cookies when generating the static page // To test the different behaviours, refresh the both /examples and /products page with JS disabled // and notice how the deviceId is properly included in the HTML with SSR (/products), unlike SSG (/examples) where it's empty // XXX This example showcase this complex behaviour. You may want to do something similar for a "Profile" section in <Nav>, // that can be rendered using both SSG/SSR depending on the page, where SSR should render the component but SSG should wait for browser re-render deps={[deviceId]} > <code>{deviceId}</code> </DisplayOnBrowserMount>
iOS_Logo_1024x1024-100.png

Uber 12 - 2021
All rights reserved

Terms
Politique de confidentialité
/static/images/LOGO_Powered_by_UNLY_BLACK_BLUE.svg