pal logo

Pal - Flutter onboarding and messages plugin

  • Create guide tours for new users<br/>
  • Ask questions and get feedbacks from your users<br/>
  • Inform about what’s new in your update<br/>
  • Improve your onboardings and app experience using analytics<br/>

πŸŽ₯ Pal introduction in video

flutter anchored onboarding screen

πŸ“± How it works ?

No code editor for all your app screens directly in your app
  • Go to a screen where you want to add helper.
  • Select your helper type.
  • Select and customize your theme.
Pal is splitted in two modes
  • Editor, create & manage helpers.
  • Client, all created helpers are displayed here.
Editor mode flow<br/>
  1. Navigate to the screen you want to show your helper.
  2. Choose how it should trigger (on first visit, on new update...)
  3. Create the helper you want with all texts, colors, fonts...
  4. Publish!
Client mode flow
  1. Fetch all onboarding on application start.
  2. Trigger an onboarding each time we detect anything that you configured for.
  3. Don't show an helper again if user has already seen it.

That's it !

πŸš€  Getting started

  • Create an administration account here.<br/>
  • Create a new project in your dashboard.<br/>
  • Get your token & save it for later.<br/>
token

Install on your flutter application now

  • Add Pal dependency
dependencies:
  ...
  pal: ^latest_version
  • Import Pal in the main.dart
import 'package:palplugin/palplugin.dart';
  • Wrap your app with Pal
void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  final _navigatorKey = GlobalKey<NavigatorState>();

  @override
  Widget build(BuildContext context) {
    return Pal(
      editorModeEnabled: true,
      appToken: 'REPLACE_WITH_YOUR_APP_TOKEN',
      // --------------------
      // YOUR APP IS HERE
      childApp: MaterialApp(
        navigatorKey: _navigatorKey,
        navigatorObservers: [PalNavigatorObserver.instance()],
        home: YourApp(),
      ),
      // --------------------
    );
  }  
}

For GetX users:

class GetXMyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Pal.fromAppBuilder(
      navigatorKey: navigatorKey,
      editorModeEnabled: false,
      appToken: 'MY_APP_TOKEN_HERE',
      childAppBuilder: (context) => GetMaterialApp(
        navigatorKey: navigatorKey,
        title: 'Pal Plugin Demo',
        navigatorObservers: [PalNavigatorObserver.instance()],
        onGenerateRoute: routes,
      ),
    );
  }
}

πŸ”₯ Configure Events

You can manually specify events within your code so we can use them to let you configure hints with editor.

Push a page

(If you use named route, you don't need to use this as we recognize automatically new pages)

   PalEvents.instance().pushPage(String routeName, {Map<String, String> arguments});

πŸŽ₯  Youtube Videos

✨  Parameters

ParamTypeDescriptionRequiredDefault
childAppWidgetyour application.βœ…
navigatorKeyGlobalKey<NavigatorState>a reference to the navigator key of your applicationchildApp.navigatorKey
navigatorObserverPalNavigatorObserverused to manage state of current pagechildApp.navigatorObservers first entry
editorModeEnabledboolenable or Disable the editor modetrue
textDirectionTextDirectiontext direction of your applicationTextDirection.ltr
appTokenStringthe app token created from the adminβœ…

πŸ™‹β€β™‚οΈπŸ™‹β€β™€οΈ Questions

Why I'm getting an error PageCreationException: EMPTY_ROUTE_PROVIDED when creating a new helper?

When you push a new route, you always need to give it an unique name if you use .push(....).

We recommend you to use .pushNamed(...) method (by using it, Pal know automatically the route name without specified it). But if you prefer using .push(...) instead, you have to create RouteSettings like this:

Navigator.push(
  context,
  MaterialPageRoute(
    settings: RouteSettings(
      name: 'page1', // <- Type here an unique route name
    )),
    builder: (context) => YourNewPage(),
);

<br/>

Why don't I see all my items as selectable when I create an anchored helper?

To detect any widget and get it back in your application we needs you to add a key on every widget you want to be selectable. For exemple to detect a container :

...
Container(
  key: ValueKey("myContainerKey"),
  ...
)

πŸ“£  Author


Initiated and sponsored by Apparence.io.

✨  More

πŸ“‘ Full documentation

🌍 Official website

Libraries

i18n
pal