Skip to content

Getting Started ​

Get up and running with Flowfull Client in minutes. This guide will walk you through installation, setup, and your first API call.

Installation ​

Install the Flowfull Client package:

bash
npm install @pubflow/flowfull-client

That's it! One package works everywhere - React, React Native, Next.js, Node.js, and any JavaScript environment.

Prerequisites ​

Before you begin, make sure you have:

  • Node.js 18+ installed
  • A Flowfull backend or Flowless instance to connect to
  • Basic knowledge of JavaScript/TypeScript

What You Need

For Basic Apps (Auth Only):

  • ✅ Flowless - Authentication service (managed at pubflow.com)
  • ✅ @pubflow/flowfull-client - This library

For Advanced Apps (Custom Business Logic):

  • ✅ Flowfull Backend - Your custom backend with business logic
  • ✅ @pubflow/flowfull-client - This library
  • ✅ Flowless (Optional) - For authentication

Quick Start ​

1. Create Your API Client ​

Create a file to export your API client:

typescript
// src/lib/api.ts (React/Vite)
// or src/lib/api.ts (Next.js)
// or src/lib/api.ts (React Native)

import { createFlowfull } from '@pubflow/flowfull-client';

export const api = createFlowfull('https://api.example.com');

Environment Variables

Use environment variables for your API URL:

React (Vite):

typescript
export const api = createFlowfull(import.meta.env.VITE_API_URL);

React Native (Expo):

typescript
export const api = createFlowfull(process.env.EXPO_PUBLIC_API_URL!);

Next.js:

typescript
export const api = createFlowfull(process.env.NEXT_PUBLIC_API_URL!);

2. Make Your First Request ​

Now you can use the API client anywhere in your app:

typescript
import { api } from './lib/api';

// GET request
const users = await api.get('/users');

// POST request
const newUser = await api.post('/users', {
  name: 'John Doe',
  email: '[email protected]'
});

// PUT request
const updated = await api.put('/users/123', {
  name: 'Jane Doe'
});

// DELETE request
await api.delete('/users/123');

3. Use in React Components ​

Here's a complete example in a React component:

typescript
import { useState, useEffect } from 'react';
import { api } from './lib/api';

function UserList() {
  const [users, setUsers] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    async function fetchUsers() {
      try {
        const data = await api.get('/users');
        setUsers(data);
      } catch (error) {
        console.error('Error fetching users:', error);
      } finally {
        setLoading(false);
      }
    }
    
    fetchUsers();
  }, []);

  if (loading) return <div>Loading...</div>;

  return (
    <ul>
      {users.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}

Platform-Specific Examples ​

React (Vite, Create React App) ​

typescript
// src/lib/api.ts
import { createFlowfull } from '@pubflow/flowfull-client';

export const api = createFlowfull(import.meta.env.VITE_API_URL);
typescript
// src/App.tsx
import { useState, useEffect } from 'react';
import { api } from './lib/api';

function App() {
  const [users, setUsers] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    api.get('/users')
      .then(setUsers)
      .catch(console.error)
      .finally(() => setLoading(false));
  }, []);

  if (loading) return <div>Loading...</div>;

  return (
    <div>
      <h1>Users</h1>
      <ul>
        {users.map(user => (
          <li key={user.id}>{user.name}</li>
        ))}
      </ul>
    </div>
  );
}

export default App;

React Native (Expo) ​

typescript
// src/lib/api.ts
import { createFlowfull } from '@pubflow/flowfull-client';

export const api = createFlowfull(process.env.EXPO_PUBLIC_API_URL!);
typescript
// src/screens/UsersScreen.tsx
import { useState, useEffect } from 'react';
import { View, Text, FlatList, ActivityIndicator, StyleSheet } from 'react-native';
import { api } from '../lib/api';

export default function UsersScreen() {
  const [users, setUsers] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    api.get('/users')
      .then(setUsers)
      .catch(console.error)
      .finally(() => setLoading(false));
  }, []);

  if (loading) {
    return (
      <View style={styles.center}>
        <ActivityIndicator size="large" />
      </View>
    );
  }

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Users</Text>
      <FlatList
        data={users}
        renderItem={({ item }) => (
          <View style={styles.item}>
            <Text>{item.name}</Text>
          </View>
        )}
        keyExtractor={(item) => item.id}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, padding: 16 },
  center: { flex: 1, justifyContent: 'center', alignItems: 'center' },
  title: { fontSize: 24, fontWeight: 'bold', marginBottom: 16 },
  item: { padding: 12, borderBottomWidth: 1, borderColor: '#ccc' },
});

Next.js (App Router) ​

typescript
// src/lib/api.ts
import { createFlowfull } from '@pubflow/flowfull-client';

export const api = createFlowfull(process.env.NEXT_PUBLIC_API_URL!);
typescript
// app/users/page.tsx
'use client';

import { useState, useEffect } from 'react';
import { api } from '@/lib/api';

export default function UsersPage() {
  const [users, setUsers] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    api.get('/users')
      .then(setUsers)
      .catch(console.error)
      .finally(() => setLoading(false));
  }, []);

  if (loading) return <div>Loading...</div>;

  return (
    <div>
      <h1>Users</h1>
      <ul>
        {users.map(user => (
          <li key={user.id}>{user.name}</li>
        ))}
      </ul>
    </div>
  );
}

Next Steps ​

Now that you have Flowfull Client installed and working, explore these guides:

Common Patterns ​

Authentication Flow ​

typescript
// Login
const response = await api.post('/auth/login', {
  email: '[email protected]',
  password: 'password123'
});

// Session is automatically stored!

// All future requests include the session
const profile = await api.get('/profile');

Error Handling ​

typescript
try {
  const users = await api.get('/users');
  setUsers(users);
} catch (error) {
  if (error.status === 401) {
    // Unauthorized - redirect to login
    navigate('/login');
  } else if (error.status === 404) {
    // Not found
    console.error('Users not found');
  } else {
    // Other errors
    console.error('Error:', error.message);
  }
}

Loading States ​

typescript
const [loading, setLoading] = useState(false);

async function fetchData() {
  setLoading(true);
  try {
    const data = await api.get('/data');
    setData(data);
  } catch (error) {
    console.error(error);
  } finally {
    setLoading(false);
  }
}

Need Help? ​