liquid_amplitude 0.2.0 copy "liquid_amplitude: ^0.2.0" to clipboard
liquid_amplitude: ^0.2.0 copied to clipboard

Amplitude destination for liquid_analytics — product analytics with user and group properties, EU residency, and opt-out.

liquid_amplitude #

Amplitude destination for liquid_analytics — product analytics with user and group properties, US/EU residency, and client-side opt-out.

Install #

dependencies:
  liquid_analytics: ^0.2.0
  liquid_amplitude: ^0.2.0

Use #

Let the sink construct Amplitude for you by passing an apiKey:

final liquid = Liquid(
  sinks: [
    AmplitudeSink(
      apiKey: 'YOUR_API_KEY',
      serverZone: ServerZone.eu, // optional residency
    ),
  ],
  consent: ConsentPolicy(
    requireOptIn: true,
    map: {ConsentCategory.analytics: ['amplitude']},
  ),
);
await liquid.init();

liquid.track('checkout_started', {
  'cart_value': 42.0,
  'is_gift': true,
  'items': ['sku_1', 'sku_2'],
});
liquid.consent.grant(ConsentCategory.analytics);

If Amplitude is already initialized elsewhere, inject the instance:

final amplitude = Amplitude(Configuration(apiKey: 'YOUR_API_KEY'));
await amplitude.isBuilt;
final liquid = Liquid(sinks: [AmplitudeSink(amplitude: amplitude)]);

The string API above is the quick path. A typed event keeps the name and property keys in one place, so the same definition feeds both event properties and the user/group properties Amplitude builds from traits:

class CheckoutStarted extends LiquidEvent {
  const CheckoutStarted({required this.cartValue, required this.items});
  final double cartValue;
  final List<String> items;

  @override
  String get name => 'checkout_started';

  @override
  Map<String, Object?> get properties => {
        'cart_value': cartValue,
        'items': items, // nested lists/maps reach Amplitude intact
      };
}

liquid.log(const CheckoutStarted(cartValue: 42, items: ['sku_1', 'sku_2']));

Override category to route an event to a different consent bucket (e.g. ConsentCategory.marketing). No build step is involved — these are plain classes. To generate them from a YAML schema instead, see liquid_codegen.

Message mapping #

liquid message Amplitude call
track track(BaseEvent)
screen track as Screen Viewed with a screen_name property
identify setUserId + identify(Identify) per trait
group setGroup + groupIdentify per trait
reset reset

Amplitude has no first-class alias API (identity is userId / deviceId), so the sink does not advertise that capability and the client skips it.

Amplitude's group model uses a (groupType, groupName) pair. liquid's single-id group('acme') maps groupName = 'acme' with the type set by groupType ('company' by default):

AmplitudeSink(apiKey: '…', groupType: 'organization');

Property handling #

Amplitude accepts nested objects, lists, booleans and numbers. AmplitudePropertyMapper therefore only:

  • drops null values, and
  • converts DateTime (to ISO-8601) and Enum (to .name) recursively.

Opt-out bridge #

Optionally mirror liquid's consent into Amplitude's client-side opt-out so the SDK itself stops sending when the user denies analytics:

final amplitudeSink = AmplitudeSink(apiKey: '…');
final liquid = Liquid(sinks: [amplitudeSink]);

liquid.consent.addListener(() {
  amplitudeSink.applyConsent(
    granted: liquid.consent.statusOf(ConsentCategory.analytics) ==
        ConsentStatus.granted,
  );
});

Testing #

AmplitudePropertyMapper is a pure transform and is unit-tested without a live project. For end-to-end checks, run against an Amplitude project and inspect User Lookup / the event stream.

0
likes
160
points
13
downloads

Documentation

API reference

Publisher

verified publisherketok.id

Weekly Downloads

Amplitude destination for liquid_analytics — product analytics with user and group properties, EU residency, and opt-out.

Homepage
Repository (GitHub)
View/report issues
Contributing

Topics

#analytics #amplitude #flutter

License

MIT (license)

Dependencies

amplitude_flutter, flutter, liquid_analytics, meta

More

Packages that depend on liquid_amplitude