# NextJS integration (App Router)

### Next.js Integration (App Router)

Follow these steps to integrate the Staysignal widget into your Next.js application:

#### 1. Create a Client Component Provider

This component handles loading the widget script (using the Site ID in the URL) and initialization. Place it in your root layout.

```typescript

// app/layout.tsx
import { StaySignalWidget } from '@/components/StaySignalWidget'; // Adjust path

export default function RootLayout({ children }: { children: React.ReactNode }) {

  const handleComplete = (payload: any) => { console.log('StaySignal Complete:', payload); };
  const handleError = (error: any) => { console.error('StaySignal Error:', error); };

  return (
    <html lang="en">
      <body>
        {children}
        {/* Render StaySignalWidget - siteId prop is only needed if not loading via /api/widget/script/[siteId] */}
        <StaySignalWidget onComplete={handleComplete} onError={handleError} />
      </body>
    </html>
  );
}
```

#### 2. Create a Cancel Button Component

```typescript
// components/CancelButton.tsx
'use client';

import { useEffect, useRef } from 'react';

interface CancelButtonProps {
  subscriptionId: string;
  className?: string;
  children?: React.ReactNode;
}

export function CancelButton({ subscriptionId, className = '', children }: CancelButtonProps) {
  const buttonRef = useRef<HTMLButtonElement>(null);

  useEffect(() => {
    const button = buttonRef.current;
    if (!button) return;

    button.classList.add('staysignal-cancel');
    button.setAttribute('data-subscription_id', subscriptionId);

    return () => {
      button.classList.remove('staysignal-cancel');
      button.removeAttribute('data-subscription_id');
    };
  }, [subscriptionId]);

  return (
    <button ref={buttonRef} className={className}>
      {children || 'Cancel Subscription'}
    </button>
  );
}
```

#### 3. Use in Your App

```typescript

// app/layout.tsx
import { StaySignalWidget } from '@/components/StaySignalWidget'; // Adjust path

export default function RootLayout({ children }: { children: React.ReactNode }) {

  const handleComplete = (payload: any) => { console.log('StaySignal Complete:', payload); };
  const handleError = (error: any) => { console.error('StaySignal Error:', error); };

  return (
    <html lang="en">
      <body>
        {children}
        {/* Render StaySignalWidget - siteId prop is only needed if not loading via /api/widget/script/[siteId] */}
        <StaySignalWidget onComplete={handleComplete} onError={handleError} />
      </body>
    </html>
  );
}
```

[Learn how to find the Stripe subscription ID](https://app.gitbook.com/o/L1J4IXndMOL7SI7HjRkS/s/vYa98TfDh2GiMvr5EyYo/~/changes/10/basics/integrations/finding-stripe-subscription-ids)

For the Pages Router, the implementation is similar but you would typically initialize the widget in \_app.tsx.

### Need Help?

If you encounter any issues with the integration, please contact our support team or refer to our documentation.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://staysignal.gitbook.io/staysignal-docs/integration-guides/nextjs-integration-app-router.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
