Skip to content

JavaScript Examples ​

Learn how to use SheetsToJson with JavaScript and TypeScript in Node.js, browsers, and modern frameworks.

Installation ​

No installation required! Use the native fetch API available in:

  • Node.js 18+
  • All modern browsers
  • Deno, Bun, and other runtimes

For older Node.js versions, install node-fetch:

bash
npm install node-fetch

Basic Usage ​

Fetch All Rows ​

javascript
const API_KEY = 'your_api_key_here';
const SHEET_ID = 'your_sheet_id';
const BASE_URL = 'https://api.sheetstojson.com';

async function getAllUsers() {
  const response = await fetch(
    `${BASE_URL}/api/v1/${SHEET_ID}/Users`,
    {
      headers: {
        'X-API-Key': API_KEY
      }
    }
  );

  const result = await response.json();

  if (result.success) {
    console.log(`Found ${result.data.length} users`);
    return result.data;
  } else {
    throw new Error(result.message);
  }
}

// Usage
const users = await getAllUsers();
console.log(users);

Fetch Single Row ​

javascript
async function getUser(userId) {
  const response = await fetch(
    `${BASE_URL}/api/v1/${SHEET_ID}/Users/${userId}`,
    {
      headers: {
        'X-API-Key': API_KEY
      }
    }
  );

  const result = await response.json();
  return result.success ? result.data : null;
}

// Usage
const user = await getUser('123');
console.log(user);

Create Row ​

javascript
async function createUser(userData) {
  const response = await fetch(
    `${BASE_URL}/api/v1/${SHEET_ID}/Users`,
    {
      method: 'POST',
      headers: {
        'X-API-Key': API_KEY,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(userData)
    }
  );

  const result = await response.json();

  if (result.success) {
    console.log('User created:', result.data.rows[0]);
    return result.data.rows[0];
  } else {
    throw new Error(result.message);
  }
}

// Usage
const newUser = await createUser({
  name: 'Alice Johnson',
  email: '[email protected]',
  role: 'admin'
});

Update Row ​

javascript
async function updateUser(userId, updates) {
  const response = await fetch(
    `${BASE_URL}/api/v1/${SHEET_ID}/Users/${userId}`,
    {
      method: 'PUT',
      headers: {
        'X-API-Key': API_KEY,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(updates)
    }
  );

  const result = await response.json();
  return result.success ? result.data : null;
}

// Usage
const updated = await updateUser('123', {
  role: 'user',
  updated_at: new Date().toISOString()
});

Delete Row ​

javascript
async function deleteUser(userId) {
  const response = await fetch(
    `${BASE_URL}/api/v1/${SHEET_ID}/Users/${userId}`,
    {
      method: 'DELETE',
      headers: {
        'X-API-Key': API_KEY
      }
    }
  );

  const result = await response.json();
  return result.success;
}

// Usage
await deleteUser('123');
console.log('User deleted');

TypeScript ​

Add type safety with TypeScript:

typescript
interface User {
  id: string;
  name: string;
  email: string;
  role: 'admin' | 'user';
  created_at?: string;
}

interface ApiResponse<T> {
  success: boolean;
  data?: T;
  error?: string;
  message?: string;
}

class SheetsToJsonClient {
  constructor(
    private apiKey: string,
    private sheetId: string,
    private baseUrl = 'https://api.sheetstojson.com'
  ) {}

  private async request<T>(
    endpoint: string,
    options: RequestInit = {}
  ): Promise<ApiResponse<T>> {
    const response = await fetch(`${this.baseUrl}${endpoint}`, {
      ...options,
      headers: {
        'X-API-Key': this.apiKey,
        'Content-Type': 'application/json',
        ...options.headers
      }
    });

    return response.json();
  }

  async getAll<T>(tabName: string, params?: {
    limit?: number;
    offset?: number;
    sort?: string;
    order?: 'asc' | 'desc';
  }): Promise<T[]> {
    const query = new URLSearchParams(
      params as Record<string, string>
    ).toString();
    const endpoint = `/api/v1/${this.sheetId}/${tabName}${query ? `?${query}` : ''}`;

    const result = await this.request<T[]>(endpoint);
    return result.success && result.data ? result.data : [];
  }

  async getOne<T>(tabName: string, rowId: string): Promise<T | null> {
    const endpoint = `/api/v1/${this.sheetId}/${tabName}/${rowId}`;
    const result = await this.request<T>(endpoint);
    return result.success && result.data ? result.data : null;
  }

  async create<T>(tabName: string, data: Partial<T>): Promise<T | null> {
    const endpoint = `/api/v1/${this.sheetId}/${tabName}`;
    const result = await this.request<{ created: number; rows: T[] }>(endpoint, {
      method: 'POST',
      body: JSON.stringify(data)
    });
    return result.success && result.data ? result.data.rows[0] : null;
  }

  async update<T>(
    tabName: string,
    rowId: string,
    data: Partial<T>
  ): Promise<T | null> {
    const endpoint = `/api/v1/${this.sheetId}/${tabName}/${rowId}`;
    const result = await this.request<T>(endpoint, {
      method: 'PUT',
      body: JSON.stringify(data)
    });
    return result.success && result.data ? result.data : null;
  }

  async delete(tabName: string, rowId: string): Promise<boolean> {
    const endpoint = `/api/v1/${this.sheetId}/${tabName}/${rowId}`;
    const result = await this.request(endpoint, { method: 'DELETE' });
    return result.success;
  }
}

// Usage
const client = new SheetsToJsonClient('your_api_key', 'your_sheet_id');

const users = await client.getAll<User>('Users', { limit: 50 });
const user = await client.getOne<User>('Users', '123');
const created = await client.create<User>('Users', {
  name: 'Bob Smith',
  email: '[email protected]',
  role: 'user'
});

React Integration ​

Using React Query ​

typescript
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';

const API_KEY = process.env.REACT_APP_API_KEY;
const SHEET_ID = process.env.REACT_APP_SHEET_ID;
const BASE_URL = 'https://api.sheetstojson.com';

// Fetch users
function useUsers() {
  return useQuery({
    queryKey: ['users'],
    queryFn: async () => {
      const response = await fetch(
        `${BASE_URL}/api/v1/${SHEET_ID}/Users`,
        { headers: { 'X-API-Key': API_KEY } }
      );
      const result = await response.json();
      return result.data;
    }
  });
}

// Create user
function useCreateUser() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (userData) => {
      const response = await fetch(
        `${BASE_URL}/api/v1/${SHEET_ID}/Users`,
        {
          method: 'POST',
          headers: {
            'X-API-Key': API_KEY,
            'Content-Type': 'application/json'
          },
          body: JSON.stringify(userData)
        }
      );
      const result = await response.json();
      return result.data.rows[0];
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['users'] });
    }
  });
}

// Component
function UsersList() {
  const { data: users, isLoading, error } = useUsers();
  const createUser = useCreateUser();

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  const handleCreate = async () => {
    await createUser.mutateAsync({
      name: 'New User',
      email: '[email protected]'
    });
  };

  return (
    <div>
      <button onClick={handleCreate}>Add User</button>
      <ul>
        {users.map(user => (
          <li key={user.id}>{user.name} - {user.email}</li>
        ))}
      </ul>
    </div>
  );
}

Using SWR ​

typescript
import useSWR from 'swr';

const fetcher = (url: string) =>
  fetch(url, {
    headers: { 'X-API-Key': process.env.REACT_APP_API_KEY }
  }).then(r => r.json()).then(result => result.data);

function UsersList() {
  const { data: users, error, mutate } = useSWR(
    `${BASE_URL}/api/v1/${SHEET_ID}/Users`,
    fetcher
  );

  if (error) return <div>Failed to load</div>;
  if (!users) return <div>Loading...</div>;

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

Next.js Integration ​

Server Component ​

typescript
// app/users/page.tsx
async function getUsers() {
  const response = await fetch(
    `${process.env.API_BASE_URL}/api/v1/${process.env.SHEET_ID}/Users`,
    {
      headers: {
        'X-API-Key': process.env.API_KEY!
      },
      next: { revalidate: 60 } // Cache for 60 seconds
    }
  );

  const result = await response.json();
  return result.data;
}

export default async function UsersPage() {
  const users = await getUsers();

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

API Route ​

typescript
// app/api/users/route.ts
import { NextResponse } from 'next/server';

export async function GET() {
  const response = await fetch(
    `${process.env.API_BASE_URL}/api/v1/${process.env.SHEET_ID}/Users`,
    {
      headers: {
        'X-API-Key': process.env.API_KEY!
      }
    }
  );

  const result = await response.json();
  return NextResponse.json(result.data);
}

export async function POST(request: Request) {
  const body = await request.json();

  const response = await fetch(
    `${process.env.API_BASE_URL}/api/v1/${process.env.SHEET_ID}/Users`,
    {
      method: 'POST',
      headers: {
        'X-API-Key': process.env.API_KEY!,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(body)
    }
  );

  const result = await response.json();
  return NextResponse.json(result.data);
}

Error Handling ​

javascript
class SheetsAPIError extends Error {
  constructor(message, code, status) {
    super(message);
    this.code = code;
    this.status = status;
  }
}

async function apiRequest(url, options = {}) {
  try {
    const response = await fetch(url, {
      ...options,
      headers: {
        'X-API-Key': API_KEY,
        'Content-Type': 'application/json',
        ...options.headers
      }
    });

    const result = await response.json();

    if (!result.success) {
      throw new SheetsAPIError(
        result.message || 'Request failed',
        result.error,
        response.status
      );
    }

    return result.data;
  } catch (error) {
    if (error instanceof SheetsAPIError) {
      throw error;
    }

    // Network or parsing error
    throw new SheetsAPIError(
      error.message,
      'network_error',
      0
    );
  }
}

// Usage with error handling
try {
  const users = await apiRequest(`${BASE_URL}/api/v1/${SHEET_ID}/Users`);
  console.log(users);
} catch (error) {
  if (error.code === 'rate_limit_exceeded') {
    console.error('Rate limit hit, try again later');
  } else if (error.code === 'unauthorized') {
    console.error('Invalid API key');
  } else {
    console.error('Request failed:', error.message);
  }
}

Next Steps ​

Built with VitePress