> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pnta.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Quick Start

> Get up and running with PNTA Flutter plugin in minutes

## Prerequisites

<Note>
  Make sure you've completed the [Platform
  Setup](/guides/flutter/platform-setup) for iOS and Android before
  proceeding.
</Note>

## How to Use

Add one line to your app's `main()` function:

```dart lib/main.dart theme={null}
import 'package:pnta_flutter/pnta_flutter.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // That's it! Handles permissions and registration automatically
  await PntaFlutter.initialize('prj_XXXXXXXXX');

  runApp(MyApp());
}
```

<Tip>
  Get your project ID from your [PNTA Dashboard](https://app.pnta.io)
  settings.
</Tip>

**That's it!** Your app now receives push notifications.

***

## Advanced Usage

### Configuration Options

You can configure optional parameters for more control:

```dart lib/main.dart theme={null}
await PntaFlutter.initialize(
  'prj_XXXXXXXXX',
  metadata: {
    'user_id': '123',
    'user_email': 'user@example.com',
  },
  registerDevice: false,  // Optional: delay registration until later
  autoHandleLinks: true,  // Optional: enable auto-handling of links
  showSystemUI: true,     // Optional: show system UI when app is in foreground
);

// Get device token after initialization/registration
final deviceToken = PntaFlutter.deviceToken;
if (deviceToken != null) {
  print('Device registered: $deviceToken');
}
```

### Delayed Registration

If you need to register the device later (e.g., after user login), use delayed registration:

```dart lib/main.dart theme={null}
void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // Initialize with metadata but don't register yet
  await PntaFlutter.initialize(
    'prj_XXXXXXXXX',
    metadata: {
      'user_id': '123',
      'user_email': 'user@example.com',
    },
    registerDevice: false,  // Don't register immediately
  );

  runApp(MyApp());
}

void _registerAfterLogin() async {
  // Register device (uses metadata from initialize)
  await PntaFlutter.registerDevice();
}
```

<Tip>
  **Best Practice:** Consider delayed registration for better opt-in rates.
  Prompt users for notifications during onboarding or after signup when they
  understand the value.
</Tip>

### Custom Notification Handling

#### Foreground Notifications

When your app is open and active, notifications arrive silently by default (no system banner). Use this to show custom UI like snackbars or dialogs:

```dart lib/main.dart theme={null}
PntaFlutter.foregroundNotifications.listen((payload) {
  print('Received foreground notification: ${payload['title']}');

  // Show custom UI (snackbar, dialog, etc.)
  ScaffoldMessenger.of(context).showSnackBar(
    SnackBar(content: Text('${payload['title']}: ${payload['body']}')),
  );

  // Manually handle links if needed
  final link = payload['link_to'] as String?;
  if (link != null && link.isNotEmpty) {
    PntaFlutter.handleLink(link);
  }
});
```

<Info>
  **iOS**: Set `showSystemUI: true` to display the standard notification
  banner when your app is in the foreground.
</Info>

<Info>
  **Android**: Set `showSystemUI: true` to make notifications appear in the
  notification panel. By default, Android foreground notifications are silent
  and don't appear in the panel. You'll need to handle in-app UI using the
  listener above.
</Info>

#### Background/Terminated Notifications

When users tap notifications while your app is in background or closed:

```dart lib/main.dart theme={null}
PntaFlutter.onNotificationTap.listen((payload) {
  print('User tapped notification: $payload');

  // Access link_to field (available on both platforms)
  final linkTo = payload['link_to'] as String?;
  
  // Track analytics, show specific screen, etc.
  // Links are auto-handled if autoHandleLinks is set to true
});
```

<Info>
  Set `autoHandleLinks: true` to automatically handle notification links.
  External URLs open in the browser, internal routes navigate within your app
  (requires navigator key setup).
</Info>

### Deep Linking Setup

For notifications that navigate to specific pages in your app:

```dart lib/main.dart theme={null}
MaterialApp(
  navigatorKey: PntaFlutter.navigatorKey, // Required for internal route navigation
  // ... rest of your app
)
```

<Info>
  Only needed if your notifications contain internal routes like `/profile`.
  External URLs with schemes (`https://`, `mailto:`, `tel:`, `sms:`) work automatically with no configuration.
</Info>

### Complete Example

This example shows multiple optional features. Remember: most apps only need the one-liner from "How to Use" above.

```dart lib/main.dart theme={null}
import 'package:flutter/material.dart';
import 'package:pnta_flutter/pnta_flutter.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // Initialize plugin - handles everything automatically
  await PntaFlutter.initialize(
    'prj_XXXXXXXXX',
    metadata: {
      'user_id': '123',
      'user_email': 'user@example.com',
    },
    autoHandleLinks: true,  // Optional: enable auto-handling of links
  );

  // App-level listeners - work everywhere, no disposal needed
  PntaFlutter.foregroundNotifications.listen((payload) {
    print('Foreground notification: ${payload['title']}');
  });

  PntaFlutter.onNotificationTap.listen((payload) {
    print('Notification tapped: ${payload['link_to']}');
  });

  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorKey: PntaFlutter.navigatorKey, // Required for deep linking
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('PNTA Example')),
      body: Center(child: Text('Ready for notifications!')),
    );
  }
}
```
