Formclick

Expo contact form

Add a contact or feedback form to your Expo app with no extra packages. It posts JSON to Formclick with fetch, so it runs in Expo Go, development builds and the web.

Get your free access key Jump to the code

Set it up in 3 steps

  1. 1

    Get your access key

    Create a free Formclick account and copy the access key for your form from the dashboard. Submissions sent with that key are delivered to your inbox.

  2. 2

    Add the component

    Copy ContactForm into your app, for example under components/, and replace YOUR_ACCESS_KEY_HERE.

  3. 3

    Open in Expo Go

    Render it on a screen, scan the QR code, send a test message and check your inbox.

The code

Replace YOUR_ACCESS_KEY_HERE with the key from your dashboard.

ContactForm.tsx
import { useState } from 'react';
import {
  View, TextInput, Pressable,
  Text, StyleSheet,
} from 'react-native';

export default function ContactForm() {
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [message, setMessage] = useState('');
  const [result, setResult] = useState('');

  async function handleSubmit() {
    setResult('Sending...');
    const res = await fetch(
      'https://api.formclick.io/submit',
      {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          Accept: 'application/json',
        },
        body: JSON.stringify({
          access_key: 'YOUR_ACCESS_KEY_HERE',
          name, email, message,
        }),
      }
    );
    const data = await res.json();
    setResult(data.message);
  }

  return (
    <View style={styles.container}>
      <TextInput style={styles.input}
        placeholder="Name"
        onChangeText={setName} value={name} />
      <TextInput style={styles.input}
        placeholder="Email"
        onChangeText={setEmail} value={email} />
      <TextInput style={[styles.input, { height: 80 }]}
        placeholder="Message"
        onChangeText={setMessage} value={message}
        multiline />
      <Pressable style={styles.button} onPress={handleSubmit}>
        <Text style={{ color: '#fff', fontWeight: '600' }}>
          Submit
        </Text>
      </Pressable>
      {result ? <Text>{result}</Text> : null}
    </View>
  );
}

const styles = StyleSheet.create({
  container: { gap: 12, padding: 16 },
  input:     { borderWidth: 1, borderColor: '#d1d5db',
               borderRadius: 8, padding: 10 },
  button:    { backgroundColor: '#645cec', borderRadius: 8,
               padding: 12, alignItems: 'center' },
});

Tips

  • Store the key in an EXPO_PUBLIC_FORMCLICK_KEY environment variable to keep it out of your source.
  • Wrap the form in KeyboardAvoidingView so the keyboard does not cover the message field.
  • The same component works with Expo Router. Put it in any route file.

Expo contact form FAQ

Does it work in Expo Go?

Yes. The example uses only fetch and core React Native components, so nothing needs a native rebuild.

Is it safe to ship my access key in client code?

Yes. The access key only allows submissions to be sent to your account. It cannot read your data, open your dashboard or change your settings, and you can restrict it to specific domains.

Do I need my own server or backend?

No. Formclick receives the submission, filters spam, stores it in your dashboard and emails it to you. Your app only makes one POST request.

How much does it cost?

Core features are free forever. Paid plans add higher submission limits and extras like file uploads. See the pricing page for details.

Other stacks

HTMLJavaScriptReactReact NativeIonicFlutterMore examples →

Your Expo form, live in minutes

Free forever on core features. No credit card required.

Create your form