Custom Component to host React Web app

Hi,

:rugby_football:
I’m a new dev, using Claude.io to help build a fantasy football app in Adalo. Most of the app uses Sheets and Google Scripts

For some of the functions Claude recommends creating a custom web view component to access a React web app hosted in GitHub pages.

:money_bag:
Would this absolutely require the $200 mo plan for api access and does the integration seem doable?

Here is the Claude convo for context, it does offer a simpler approach as well. Which i attached as a screenshot.

:laptop:
I will need to hire a developer consultant soon, but trying to make the connections between Adalo-Sheets-Script-React.

“Now that you have developer mode enabled in Adalo, here are the next steps to complete your fantasy football integration:

Step 1: Create a React Web App for Google Sheets Integration

Before you can use the custom component code you shared, you need to create a React web app that will:

  1. Communicate with Google Sheets using your service account
  2. Render your fantasy football feed interface
  3. Be hosted somewhere accessible to your Adalo app

Here’s a simplified approach:

// Simple React app to communicate with Google Sheets
import React, { useState, useEffect } from 'react';
import { gapi } from 'gapi-script';

function FantasyFootballApp() {
  const [plays, setPlays] = useState([]);
  const [loading, setLoading] = useState(true);
  
  // Parse configuration from URL params or window.ADALO_CONFIG
  const config = window.ADALO_CONFIG || {
    apiKey: new URLSearchParams(window.location.search).get('apiKey'),
    spreadsheetId: new URLSearchParams(window.location.search).get('spreadsheetId'),
    refreshInterval: parseInt(new URLSearchParams(window.location.search).get('refreshInterval') || '60')
  };
  
  // Fetch data from Google Sheets
  const fetchData = async () => {
    try {
      setLoading(true);
      
      // Initialize Google Sheets API
      await gapi.client.init({
        apiKey: config.apiKey,
        discoveryDocs: ['https://sheets.googleapis.com/$discovery/rest?version=v4'],
      });
      
      // Get data from the "Plays" sheet
      const response = await gapi.client.sheets.spreadsheets.values.get({
        spreadsheetId: config.spreadsheetId,
        range: 'Plays!A1:M50', // Adjust range as needed
      });
      
      // Process the data
      const headers = response.result.values[0];
      const rows = response.result.values.slice(1);
      const processedPlays = rows.map(row => {
        const play = {};
        headers.forEach((header, index) => {
          play[header] = row[index];
        });
        return play;
      });
      
      setPlays(processedPlays);
      
      // Send message back to Adalo
      window.ReactNativeWebView?.postMessage(JSON.stringify({
        type: 'DATA_READY',
        data: processedPlays
      }));
    } catch (error) {
      console.error('Error fetching data:', error);
    } finally {
      setLoading(false);
    }
  };
  
  // Define refresh function globally so it can be called from injected JS
  useEffect(() => {
    window.refreshData = fetchData;
    
    // Load the Google API client
    const script = document.createElement('script');
    script.src = 'https://apis.google.com/js/api.js';
    script.onload = () => {
      gapi.load('client', fetchData);
    };
    document.body.appendChild(script);
    
    return () => {
      delete window.refreshData;
    };
  }, []);
  
  // Render the fantasy football feed
  return (
    <div className="fantasy-football-feed">
      <h2>Fantasy Football Feed</h2>
      
      {loading ? (
        <div className="loading">Loading plays...</div>
      ) : (
        <div className="plays-list">
          {plays.map(play => (
            <div key={play.Id} className="play-card">
              <div className="play-header">
                <span className="game-time">Q{play.Quarter} - {Math.floor(play.GameClock / 60)}:{(play.GameClock % 60).toString().padStart(2, '0')}</span>
                <span className="yards">{play.Yards > 0 ? '+' : ''}{play.Yards} yds</span>
              </div>
              <div className="play-description">{play.Description}</div>
              <div className="play-footer">
                <span className="down-distance">{play.Down}&{play.Distance}</span>
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

export default FantasyFootballApp;

Step 2: Host Your React App

You need to host this React app somewhere accessible to Adalo. Options include:

  • Vercel
  • Netlify
  • GitHub Pages
  • Firebase Hosting

After deploying, you’ll get a URL like https://your-fantasy-football-app.vercel.app to use in the next step.

Step 3: Create and Publish Your Custom Adalo Component

Now use the code you shared to create the custom component:

  1. Create a new directory for your component:

    npx @adalo/cli init fantasy-football-component
    cd fantasy-football-component
    
  2. Replace the component files with your code:

    • Replace manifest.json with the configuration you shared
    • Create src/components/WebView.js with the component code
  3. Update the URL in the default props to point to your hosted React app

  4. Build and publish the component:

    npm run build
    npx @adalo/cli login
    npx @adalo/cli publish
    

Step 4: Add the Component to Your Adalo App

  1. In Adalo, create a new screen or open an existing one
  2. In the Components panel, find your “Web View with Sheets Integration” component
  3. Drag it onto your screen
  4. Configure the properties:
    • Web View URL: Your hosted React app URL
    • Google Sheets API Key: Your API key
    • Spreadsheet ID: Your Google Sheet ID
    • Refresh Interval: How often to refresh (e.g., 30 seconds)

Step 5: Configure Authentication (Service Account)

For the service account to work properly:

  1. In your React app, add code to authenticate with your service account:

    // Use a library like google-auth-library
    const { GoogleAuth } = require('google-auth-library');
    
    const auth = new GoogleAuth({
      keyFile: 'path/to/your/service-account-key.json', // You'll need to include this in your app
      scopes: ['https://www.googleapis.com/auth/spreadsheets.readonly']
    });
    
    const authClient = await auth.getClient();
    
  2. Make sure your service account has appropriate access to the Google Sheet

  3. Set up CORS if needed to allow your Adalo app to communicate with your React app

Alternative Simpler Approach

If building a custom component feels too complex, you could also:

  1. Create a Google Apps Script web app that serves your sheet data as JSON
  2. Use Adalo’s native WebView component to display a simple React app that fetches from that endpoint
  3. This approach would be simpler but less integrated with Adalo’s UI

Would you like me to explain any of these steps in more detail?​​​​​​​​​​​​​​​​“

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.