Building Custom React Frontends (FlowDot Apps)

Create custom React user interfaces for your workflows. Learn the App Editor, workflow linking, AI-assisted development, and display modes.

Building Custom React Frontends (FlowDot Apps)

FlowDot Apps let you create custom React interfaces for your workflows. Build interactive UIs that connect to your automations without deployment hassle.

What You'll Learn


Part 1: Understanding FlowDot Apps

What Are Apps?

Apps are custom React frontends that:

App vs Dashboard

Dashboard App
Auto-generated UI Custom coded UI
Standard form layout Any design you want
Limited customization Full React power
Quick to use Takes time to build

Part 2: Creating Your First App

Step 1: Navigate to Apps

  1. Click Apps in the navigation
  2. Click My Apps
  3. Click Create New App

Step 2: Name Your App

  1. Enter a name (e.g., "Goat Frontend")
  2. Click Create

Step 3: The App Editor

You'll see:


Part 3: App Code Basics

Environment Rules

FlowDot Apps run in a special environment:

Rule Example
No imports React is global
No exports Just define your function
Function naming function MyApp() { }
Styling Tailwind CSS only

Starter Code

function GoatFrontend() {
  const [count, setCount] = React.useState(0);
  
  return (
    <div className="p-4">
      <h1 className="text-2xl font-bold">Hello FlowDot!</h1>
      <button 
        onClick={() => setCount(count + 1)}
        className="bg-primary-600 text-white px-4 py-2 rounded mt-4"
      >
        Count: {count}
      </button>
    </div>
  );
}

Available Globals


Part 4: Linking Workflows

Why Link?

To call a workflow from your app, it must be linked first.

How to Link

  1. In the App Editor, click Link Workflows (sidebar)
  2. Browse your workflows
  3. Click a workflow to see its inputs/outputs
  4. Click Link

Viewing Linked Workflows

After linking:


Part 5: Invoking Workflows

Basic Invocation

function MyApp() {
  const [result, setResult] = React.useState(null);
  const [loading, setLoading] = React.useState(false);
  
  const runWorkflow = async () => {
    setLoading(true);
    const response = await invokeWorkflow('aB3xY9kL2m', {
      user_prompt: 'Do you prefer hay or grain?'
    });
    setResult(response);
    setLoading(false);
  };
  
  return (
    <div className="p-4">
      <button 
        onClick={runWorkflow}
        disabled={loading}
        className="bg-primary-600 text-white px-4 py-2 rounded"
      >
        {loading ? 'Running...' : 'Ask the Goat'}
      </button>
      
      {result && (
        <pre className="mt-4 p-4 bg-gray-100 rounded">
          {JSON.stringify(result, null, 2)}
        </pre>
      )}
    </div>
  );
}

Input Mapping

The second argument maps to your workflow's inputs:

await invokeWorkflow('hash', {
  user_prompt: userInput,      // Maps to "User Prompt" input node
  system_prompt: systemPrompt  // Maps to "System Prompt" input node
});

Handling Results

const response = await invokeWorkflow('hash', inputs);

// Response structure
{
  data: {
    "node-id-1": {
      nodeTitle: "LLM Query",
      outputs: {
        response: { value: "Baa! I love hay!" }
      }
    }
  }
}

// Extract what you need
const llmOutput = Object.values(response.data)
  .find(n => n.nodeTitle === 'LLM Query')
  ?.outputs?.response?.value;

Part 6: AI-Assisted Development

Using the AI Assistant

  1. Click the AI Assistant icon in the App Editor
  2. Select your model tier (Complex recommended)
  3. Describe what you want:
You: Build the most fun and cute goat simulator frontend.

What the AI Sees

The assistant has access to:

Iterative Development

You: Add a text input for the user's question.
[Apply changes]

You: Make the goat response appear in a speech bubble.
[Apply changes]

You: Add some cute goat emojis and animations.
[Apply changes]

Part 7: Display Modes

Available Modes

Mode Description Use Case
Windowed Standard view with FlowDot header Default, branded
Fullscreen Full viewport, minimal controls Immersive apps
Embedded No FlowDot UI at all iframe embedding

Setting Display Mode

  1. Click the hamburger menu in App Editor
  2. Find Display Mode
  3. Select your preference
  4. Save

Example: Fullscreen App

For a kiosk or dedicated app experience:

  1. Set Display Mode to Fullscreen
  2. Design edge-to-edge layout
  3. Include your own navigation if needed

Part 8: Complete App Example

function GoatSimulator() {
  const [question, setQuestion] = React.useState('');
  const [response, setResponse] = React.useState('');
  const [loading, setLoading] = React.useState(false);
  
  const askGoat = async () => {
    if (!question.trim()) return;
    
    setLoading(true);
    setResponse('');
    
    try {
      const result = await invokeWorkflow('YOUR_WORKFLOW_HASH', {
        user_prompt: question
      });
      
      // Extract the goat's response
      const goatResponse = Object.values(result.data)
        .find(n => n.nodeTitle === 'LLM Query')
        ?.outputs?.response?.value || 'The goat is speechless!';
      
      setResponse(goatResponse);
    } catch (error) {
      setResponse('Baa! Something went wrong!');
    }
    
    setLoading(false);
  };
  
  return (
    <div className="min-h-screen bg-gradient-to-b from-green-100 to-green-200 p-8">
      <div className="max-w-2xl mx-auto">
        <h1 className="text-4xl font-bold text-center text-green-800 mb-8">
          Ask Gerald the Goat
        </h1>
        
        <div className="bg-white rounded-lg shadow-lg p-6">
          <input
            type="text"
            value={question}
            onChange={(e) => setQuestion(e.target.value)}
            placeholder="Ask the goat anything..."
            className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-green-500"
            onKeyPress={(e) => e.key === 'Enter' && askGoat()}
          />
          
          <button
            onClick={askGoat}
            disabled={loading}
            className="w-full mt-4 bg-green-600 text-white py-3 rounded-lg hover:bg-green-700 disabled:opacity-50 transition"
          >
            {loading ? 'Thinking...' : 'Ask Gerald'}
          </button>
        </div>
        
        {response && (
          <div className="mt-6 bg-white rounded-lg shadow-lg p-6">
            <div className="flex items-start gap-4">
              <span className="text-4xl">goat emoji</span>
              <div className="flex-1 bg-green-50 rounded-lg p-4">
                <p className="text-green-800">{response}</p>
              </div>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

Part 9: Publishing and Sharing

Making Your App Public

  1. Open App settings
  2. Set visibility to Public
  3. Save

Sharing Options


Summary

FlowDot Apps give you:

Start simple, iterate with AI help, and create polished experiences for your workflows!

Congratulations - you've completed the FlowDot tutorials!

Related Tutorials

Back to Tutorials