Using Resend

Edit page

Learn how to integrate Resend in your Expo and React Native app to programmatically send emails with Expo Router's API Routes.


Resend is an email API platform designed for developers. It allows you to send, receive, and manage emails programmatically through an API. You can use it to send transactional emails for use cases like newsletters, marketing emails, and more. The API also allows you to set up webhooks for email events, manage domains for deliverability, and receive emails via webhooks.

This guide demonstrates the essential steps to integrate Resend with your Expo and React Native project.

How to send emails with Resend from your Expo app
How to send emails with Resend from your Expo app

Prerequisites

Before you get started, you need to have the following:

1

Create a Resend API key

Go to the Resend dashboard > API Keys and click on Create API Key to generate an API key.

Once you have generated the API key, save it to .env.local file in your Expo project:

.env.local
RESEND_API_KEY=YOUR_RESEND_API_KEY

Note: Do not commit .env.local file to your Version Control System (VCS) like Git. The API key is sensitive and should not be exposed to the public. You must add the file to your .gitignore file to ignore it.

2

Install Resend SDK

In your Expo project, install the Resend SDK using the following command:

Terminal
npx expo install resend

The resend SDK library is a server-only library. It allows you to send emails from the server-side code of your app. Since this guide uses API Routes to handle email submissions, you need to install the resend as part of your Expo project.

3

Enable and create an API route

To enable using API Routes in your Expo project, you need to set the web.output to server in your app config file:

app.json
{ "web": { "output": "server" } }

Then, create an API route to handle email submissions. Inside the app directory, create a new file called api/audience+api.ts. The +api.ts extension is used by Expo Router to identify the file as an API Route. To test the integration, you can add the minimal code below to send an email to a recipient using Resend SDK:

app/api/audience+api.ts
import { Resend } from 'resend'; const resend = new Resend(process.env.RESEND_API_KEY); export async function POST(request: Request) { const body = await request.json(); const { email } = body; if (!email) { return Response.json({ success: false }); } await resend.contacts.create({ email: email, // Provide dynamic values on your own firstName: 'Steve', lastName: 'Wozniak', unsubscribed: false, }); return Response.json({ success: true }); }

In the above code snippet, the POST request function is executed when the /api/audience route is matched. The function receives a Request object as an argument, which contains the HTTP request body. Then, the function extracts the email from the request body and sends it to the Resend API to add it to the audience.

4

Add a base URL

To make the API route accessible from your Expo app, you need to add the base URL as an environment variable in your Expo project. Add the following code to your .env.local file:

.env.local
EXPO_PUBLIC_BASE_URL=https://example-resend.expo.app # Deployed URL via EAS Hosting EXPO_PUBLIC_BASE_URL_LOCAL=http://localhost:8081 # Only required for testing locally

To test Resend integration locally, you can use EXPO_PUBLIC_BASE_URL_LOCAL to point to your local development server, whose URL is provided when you run npx expo start. Later in this guide, when you deploy your app to EAS Hosting, ensure to update the EXPO_PUBLIC_BASE_URL to the deployed URL.

Note that only variables prefixed with EXPO_PUBLIC_ can be used in the frontend code, so you can have the above as well as the Resend API key in the same .env file, but the RESEND_API_KEY will only be accessible from the server-side code (that is, files ending with +api).

5

Add a form to your Expo project

The following example code shows a simple form to collect email addresses from app users. In a real-world scenario, you would want to add validation and error handling to the form. For example, the following code is added to the app/index.tsx file:

app/index.tsx
import { useRef, useState } from 'react'; import { Alert, Pressable, StyleSheet, Text, TextInput, View } from 'react-native'; export default function Index() { const [email, setEmail] = useState(''); const inputRef = useRef<TextInput>(null); const handleSubmit = async () => { if (!email) { alert('Email is required.'); return; } if (inputRef.current) { inputRef.current.blur(); } try { const response = await fetch( `${process.env.EXPO_PUBLIC_BASE_URL_LOCAL}/api/audience`, // Switch to `EXPO_PUBLIC_BASE_URL` after deploying to EAS Hosting { method: 'POST', body: JSON.stringify({ email }), } ); // You can handle other response validations here. await response.json(); Alert.alert('Success', 'Email sent successfully.', [ { text: 'Continue', }, ]); } catch (error) { alert('Something went wrong.'); console.error(error); } }; return ( <View style={styles.container}> <TextInput placeholder="Email" value={email} onChangeText={setEmail} ref={inputRef} autoCapitalize="none" keyboardType="email-address" style={styles.input} /> <Pressable style={styles.button} onPress={handleSubmit}> <Text style={styles.buttonText}>Send email</Text> </Pressable> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', }, input: { borderWidth: 1, borderColor: 'gray', padding: 10, width: '60%', height: '6%', borderRadius: 10, marginBottom: 10, margin: 20, }, button: { padding: 10, backgroundColor: '#000000', borderRadius: 10, }, buttonText: { color: 'white', textAlign: 'center', }, });

6

Deploy the API route to EAS Hosting

To make the API route (/api/audience) accessible from a URL, you can deploy it to EAS Hosting.

  1. Run the following command to export the web and API assets. The exported files are saved inside a dist directory and the API route file is part of this directory:
Terminal
npx expo export --platform web
  1. Run the following to create a production deployment via EAS Hosting:
Terminal
eas deploy --prod

The eas deploy --prod command will:

  • Automatically create an EAS project if you haven't already
  • Prompt you to choose the preview URL for your project. Ensure that this URL is the same as the value of EXPO_PUBLIC_BASE_URL in your .env.local file. This will make the API route accessible from your Expo app while deployed in production

Note: Before deployment, you need to use the EXPO_PUBLIC_BASE_URL as your hosted domain in your form screen (app/index.tsx).

Learn more about Resend

For more information about Resend's API and usage, see Resend's official documentation.