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: 'john@example.com'
});

// 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: 'user@example.com',
  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?