---
title: "Handlinger efter installation og onboarding | Tajo"
description: "Konfigurer, hvad der sker efter installationen, og byg effektive onboardingforløb til din Stripe App"
url: https://tajo.io/dk/docs/stripe-apps/post-install/
markdown: https://tajo.io/dk/docs/stripe-apps/post-install.md
lang: da-DK
author: "Set Noa"
author_url: https://tajo.io/dk/set-noa/
robots: noindex
---

Bed om tidlig adgang til Tajo

Indtast dit fornavn og din arbejds-e-mailadresse. Vi sender dig et link til at bekræfte din anmodning om adgang til Tajo.

# Handlinger efter installation og onboarding

[Set Noa](https://tajo.io/dk/set-noa/)

Handlinger efter installation bestemmer, hvad der sker umiddelbart efter, at en bruger har installeret din Stripe App. En gennemtænkt oplevelse efter installationen guider brugerne gennem opsætningen og øger antallet af aktiveringer.

Caution

**Status: planlagt, ikke bygget.** Tajo har ingen Stripe-app, så intet i dette afsnit kan installeres i dag. App-ID’er, URL’er og loginoplysninger på denne side er illustrative pladsholdere, ikke aktive endpoints.

## Typer af handlinger efter installation

Stripe understøtter fire typer handlinger efter installation, som alle konfigureres i dit app-manifest:

### 1. Link til appen (standard)

Åbner appen i standardvisningen i skuffen. Det er standardadfærden, hvis der ikke er angivet en `post_install_action`:

```json
{
  "post_install_action": {
    "type": "default"
  }
}
```

Brugeren ser appens `drawer.default`-viewport i sidemenuen i Stripe Dashboard.

### 2. Link til onboarding

Åbner appens dedikerede onboardingvisning og giver en fokuseret opsætningsoplevelse:

```json
{
  "post_install_action": {
    "type": "onboarding"
  }
}
```

Det kræver, at der er erklæret en `onboarding`-viewport i dit manifest:

```json
{
  "ui_extension": {
    "views": [
      {
        "viewport": "stripe.dashboard.onboarding",
        "component": "OnboardingView"
      }
    ]
  },
  "post_install_action": {
    "type": "onboarding"
  }
}
```

### 3. Link til indstillinger

Åbner appens indstillinger, hvilket er nyttigt, når appen kræver API-nøgler eller konfiguration, før den kan bruges:

```json
{
  "post_install_action": {
    "type": "settings"
  }
}
```

Det kræver en `settings`-viewport:

```json
{
  "ui_extension": {
    "views": [
      {
        "viewport": "stripe.dashboard.settings",
        "component": "SettingsView"
      }
    ]
  },
  "post_install_action": {
    "type": "settings"
  }
}
```

### 4. Link til ekstern URL

Sender brugeren videre til en ekstern URL for at gennemføre opsætningen. Brug den, når dit onboardingforløb ligger uden for Stripe Dashboard:

```json
{
  "post_install_action": {
    "type": "external",
    "url": "https://app.tajo.io/stripe/setup"
  }
}
```

Caution

Eksterne URL’er skal bruge HTTPS og bør stå i dine `allowed_redirect_uris`. Stripes review-team kontrollerer, at den eksterne URL giver en opsætningsoplevelse, der rent faktisk virker.

## Bedste praksis for onboarding

### Gør det ubesværet

Hold antallet af trin, der skal til for at komme i gang, nede:

- **Udfyld oplysninger på forhånd** ud fra konteksten i Stripe-kontoen
- **Brug fornuftige standardværdier** til konfigurationsvalgene
- **Lad brugeren springe over** valgfrie trin, og vis tydeligt, hvordan de gennemføres senere
- **Vis fremdriften** med trinindikatorer i forløb med flere trin

### Gør det fleksibelt

Lad brugerne tilpasse integrationen til deres behov:

- **Muligheder for datamapning**, lad brugerne vælge, hvilke Stripe-felter der synkroniseres til Brevo
- **Synkroniseringsfrekvens**, tilbyd synkronisering hver time eller dagligt
- **Selektiv synkronisering**, lad brugerne vælge, hvilke kunder eller produkter der skal synkroniseres
- **Notifikationsindstillinger**, konfigurer advarsler ved synkroniseringsfejl eller vigtige hændelser

### Gør det relevant

Vis værdien med det samme:

- **Vis et eksempel på de synkroniserede data**, før integrationen slås til
- **Fortæl, hvad der sker**, når brugeren gennemfører opsætningen
- **Tilbyd en testsynkronisering**, så brugeren kan se, at forbindelsen virker
- **Vis resultater**, når den første synkronisering er færdig

## OnboardingView-komponenten

Komponenten `OnboardingView` vises i et fokuseret vindue, når brugeren installerer appen:

```typescript
import {
  Box,
  Button,
  Inline,
  Icon,
  Banner,
  TextField,
  Select,
  Divider,
} from '@stripe/ui-extension-sdk/ui';
import type { ExtensionContextValue } from '@stripe/ui-extension-sdk/context';
import { useState } from 'react';

const OnboardingView = ({ environment, userContext }: ExtensionContextValue) => {
  const [step, setStep] = useState(1);
  const [brevoApiKey, setBrevoApiKey] = useState('');
  const [syncMode, setSyncMode] = useState('hourly');
  const [isConnecting, setIsConnecting] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const totalSteps = 3;

  const handleConnect = async () => {
    setIsConnecting(true);
    setError(null);

    try {
      // Store the API key securely
      await storeBrevoApiKey(brevoApiKey);

      // Verify the connection
      const result = await verifyBrevoConnection(brevoApiKey);

      if (result.success) {
        setStep(2);
      } else {
        setError('Unable to connect to Brevo. Please check your API key.');
      }
    } catch (err) {
      setError('Connection failed. Please try again.');
    } finally {
      setIsConnecting(false);
    }
  };

  return (
    <Box css={{ padding: 'large' }}>
      {/* Progress indicator */}
      <Inline css={{ marginBottom: 'large' }}>
        Step {step} of {totalSteps}
      </Inline>

      {error && (
        <Banner type="critical" title="Connection Error">
          {error}
        </Banner>
      )}

      {step === 1 && (
        <Box>
          <Inline css={{ fontWeight: 'bold', fontSize: 'large' }}>
            Connect Your Brevo Account
          </Inline>
          <Inline css={{ marginTop: 'small', color: 'secondary' }}>
            Enter your Brevo API key to start syncing customer data.
          </Inline>

          <TextField
            label="Brevo API Key"
            placeholder="xkeysib-..."
            value={brevoApiKey}
            onChange={(e) => setBrevoApiKey(e.target.value)}
            css={{ marginTop: 'medium' }}
          />

          <Inline css={{ marginTop: 'xsmall', color: 'secondary', fontSize: 'small' }}>
            Find your API key in Brevo under Settings &gt; SMTP &amp; API &gt; API Keys
          </Inline>

          <Button
            type="primary"
            onPress={handleConnect}
            disabled={!brevoApiKey || isConnecting}
            css={{ marginTop: 'medium' }}
          >
            {isConnecting ? 'Connecting...' : 'Connect Brevo'}
          </Button>
        </Box>
      )}

      {step === 2 && (
        <Box>
          <Inline css={{ fontWeight: 'bold', fontSize: 'large' }}>
            Configure Sync Settings
          </Inline>

          <Select
            label="Sync Mode"
            value={syncMode}
            onChange={(value) => setSyncMode(value)}
            css={{ marginTop: 'medium' }}
          >
            <option value="hourly">Every hour</option>
            <option value="daily">Once per day</option>
          </Select>

          <Divider css={{ marginY: 'medium' }} />

          <Button type="primary" onPress={() => setStep(3)}>
            Continue
          </Button>
          <Button type="secondary" onPress={() => setStep(1)}>
            Back
          </Button>
        </Box>
      )}

      {step === 3 && (
        <Box>
          <Banner type="default" title="Ready to Sync">
            Your Brevo account is connected. Tajo will begin syncing
            customer data automatically.
          </Banner>

          <Box css={{ marginTop: 'medium' }}>
            <Inline css={{ fontWeight: 'bold' }}>What happens next:</Inline>
            <ul>
              <li>Existing Stripe customers will sync to Brevo contacts</li>
              <li>New customers will sync on the schedule you chose</li>
              <li>View sync status on any customer's detail page</li>
            </ul>
          </Box>

          <Button type="primary" onPress={() => {/* Navigate to dashboard */}}>
            Go to Dashboard
          </Button>
        </Box>
      )}
    </Box>
  );
};

export default OnboardingView;
```

## Login-flow med SignInView

Hvis din app kræver, at brugerne logger ind på en ekstern konto (for eksempel Tajo), skal du bruge en dedikeret loginvisning:

```typescript
import {
  Box,
  Button,
  Inline,
  TextField,
  Banner,
  Link,
} from '@stripe/ui-extension-sdk/ui';
import { useState } from 'react';

const SignInView = ({ onSignInComplete }) => {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const handleSignIn = async () => {
    setIsLoading(true);
    setError(null);

    try {
      const response = await fetch('https://api.example.com/v1/auth/stripe-app', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ email, password }),
      });

      if (!response.ok) {
        throw new Error('Invalid credentials');
      }

      const { token } = await response.json();

      // Store the auth token securely in Stripe's Secret Store
      await storeAuthToken(token);

      onSignInComplete();
    } catch (err) {
      setError('Sign-in failed. Please check your credentials and try again.');
    } finally {
      setIsLoading(false);
    }
  };

  return (
    <Box css={{ padding: 'large' }}>
      <Inline css={{ fontWeight: 'bold', fontSize: 'large' }}>
        Sign in to Tajo
      </Inline>
      <Inline css={{ marginTop: 'small', color: 'secondary' }}>
        Connect your Tajo account to enable Brevo sync.
      </Inline>

      {error && (
        <Banner type="critical" title="Sign-in Failed">
          {error}
        </Banner>
      )}

      <TextField
        label="Email"
        type="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        css={{ marginTop: 'medium' }}
      />

      <TextField
        label="Password"
        type="password"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
        css={{ marginTop: 'small' }}
      />

      <Button
        type="primary"
        onPress={handleSignIn}
        disabled={!email || !password || isLoading}
        css={{ marginTop: 'medium' }}
      >
        {isLoading ? 'Signing in...' : 'Sign In'}
      </Button>

      <Link href="https://app.tajo.io/signup" external css={{ marginTop: 'small' }}>
        Don't have a Tajo account? Sign up
      </Link>
    </Box>
  );
};
```

## Deep links med forespørgselsparametre

Du kan åbne bestemte onboardingtrin eller udfylde data på forhånd ved hjælp af forespørgselsparametre i deep links:

```typescript
import type { ExtensionContextValue } from '@stripe/ui-extension-sdk/context';

const OnboardingView = ({ environment }: ExtensionContextValue) => {
  // Access query parameters from the deep link
  const { queryParams } = environment;

  // Pre-fill step from query parameter
  const initialStep = queryParams?.step ? parseInt(queryParams.step) : 1;

  // Pre-fill API key from query parameter (e.g., from Tajo dashboard)
  const prefilledApiKey = queryParams?.brevo_key || '';

  // Source tracking for analytics
  const installSource = queryParams?.source || 'marketplace';

  const [step, setStep] = useState(initialStep);
  const [brevoApiKey, setBrevoApiKey] = useState(prefilledApiKey);

  // ... rest of onboarding logic
};
```

Generer deep links, der udfylder onboardingdata på forhånd:

```javascript
// From your Tajo dashboard, generate a link that pre-fills the Brevo API key
const onboardingLink = [
  'https://dashboard.stripe.com/live/acct_xxxxx/dashboard',
  '?apps[com.tajo.brevo-integration][modal]=stripe.dashboard.onboarding',
  '&apps[com.tajo.brevo-integration][queryParams][step]=1',
  '&apps[com.tajo.brevo-integration][queryParams][source]=tajo_dashboard',
].join('');
```

## Håndtering af tilbagevendende brugere

Når en bruger åbner din app efter at have gennemført onboardingen, skal du finde ud af, hvor brugeren er nået til, og vise den rigtige visning:

```typescript
const MainView = ({ environment, userContext }: ExtensionContextValue) => {
  const [authState, setAuthState] = useState<'loading' | 'signed-out' | 'onboarding' | 'ready'>('loading');

  useEffect(() => {
    checkUserState().then((state) => {
      setAuthState(state);
    });
  }, []);

  switch (authState) {
    case 'loading':
      return <Spinner label="Loading..." />;
    case 'signed-out':
      return <SignInView onSignInComplete={() => setAuthState('onboarding')} />;
    case 'onboarding':
      return <OnboardingView onComplete={() => setAuthState('ready')} />;
    case 'ready':
      return <DashboardView />;
  }
};
```

Tip

Gem status for gennemført onboarding i Stripe Secret Store, så du kan genkende tilbagevendende brugere uden at kalde et eksternt API.
