How to Share from a React Native App (including the Web)
Tags: reactnative, mobiledevelopment
Published: 2022-08-15 20:52:13

---
title: How to Share from a React Native App (including the Web)
published: true
description: Learn how to customize your functions to compensate for differing API support on multiple platforms.
tags: reactnative, mobiledevelopment
# cover_image: https://direct_url_to_image.jpg
# Use a ratio of 100:42 for best results.
canonical_url: https://www.reactnativeschool.com/how-to-share-from-a-react-native-app-including-the-web
---


React Native's web support continues to get better and better, especially if you're using Expo. With Expo it just works out of the box.

But adding another supported platform to your app adds complexity! You've got to make sure things work on each supported platform.

Recently I was [building a game with React Native](https://github.com/ReactNativeSchool/match-the-pairs-react-native), Match the Pairs, that allows a user to share how many moves it took them to beat the game.

It runs on iOS, Android, and the web. React Native's `Share` API works on iOS and Android but not the web so I had to come up with a solution to handle this.

Today we'll cover how to build a function that has differing functionality depending on what platform it runs on.

## The shareGame Function

First we'll create the function that will be called when a user presses "Share game" in the app.

![Screenshots of match the pair on iOS, Android, and the web](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pcub5ho03y94x14rjrqj.png)

```ts
type shareGameProps = {
  emojis: string[]
  moveCount: number
}

export const shareGame = async ({ emojis, moveCount }: shareGameProps) => {}
```

Example input:

```ts
shareGame({
  emojis: [
    "🏄",
    "💣",
    "📬",
    "😇",
    "🤠",
    "🦦",
    "📸",
    "📬",
    "🤠",
    "🏄",
    "🌮",
    "🌮",
    "💣",
    "😇",
    "🦦",
    "📸",
  ],
  moveCount: 16,
})
```

## The Share API

First we can take advantage of the [`Share` API](https://reactnative.dev/docs/share) from React Native.

```ts
import { Share } from "react-native"

type shareGameProps = {
  emojis: string[]
  moveCount: number
}

export const shareGame = async ({ emojis, moveCount }: shareGameProps) => {
  const message = "This is an example message"

  return await Share.share({
    message,
  })
}
```

On iOS and Android this works great but the web throws an error that it isn't supported.

![Share dialogs on iOS and Android and an error message on the web](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ppd1zoq76pm6jm1hkvkz.png) 

## Leveraging the Platform API

So, what can we do about this differing API support between platforms?

We can leverage the core `Platform` API to change the functionality on a given platform.

```ts
import { Share, Platform } from "react-native"
import * as Clipboard from "expo-clipboard"

type shareGameProps = {
  emojis: string[]
  moveCount: number
}

export const shareGame = async ({ emojis, moveCount }: shareGameProps) => {
  const message = "This is an example message"

  if (Platform.OS === "web") {
    await Clipboard.setStringAsync(message)

    alert(`The following message was copied to your clipboard.\n\n${message}`)
    return
  }

  return await Share.share({
    message,
  })
}
```

Above you can see that if the platform is "web" we'll copy the message to their clipboard (via [`expo-clipboard`](https://docs.expo.dev/versions/latest/sdk/clipboard/) or [`react-native-clipboard`](https://github.com/react-native-clipboard/clipboard)).

We're also using `alert` to notify the user that we copied the message to the clipboard and what the actual message was. A custom modal would be an even better solution here.

If the platform isn't "web" then we'll continue on to use the `Share` API.

![The web version of the app alerting that something has been copied to the clipboard](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ge3v9m28rd7jeqtzz5i.png) 

## Bonus: Building the Share Message

This section isn't really pertinent to the content of this article but I figured I'd add it in. Let's create the actual message.

We want to create the grid of emojis that the user played, like this:

```txt
🏄 💣 📬 😇
🤠 🦦 📸 📬
🤠 🏄 🌮 🌮
💣 😇 🦦 📸
```

To do so we'll split our array of emojis into 4 rows of 4 emojis and then join them with a new line character.

```ts
import { Share, Platform } from "react-native"
import * as Clipboard from "expo-clipboard"

type shareGameProps = {
  emojis: string[]
  moveCount: number
}

const buildRow = (emojis: string[], start: number, end: number) =>
  emojis.slice(start, end).join(" ")

export const shareGame = async ({ emojis, moveCount }: shareGameProps) => {
  const row1 = buildRow(emojis, 0, 4)
  const row2 = buildRow(emojis, 4, 8)
  const row3 = buildRow(emojis, 8, 12)
  const row4 = buildRow(emojis, 12, 16)

  const emojiBoard = [row1, row2, row3, row4].join("\n")
  const message = `I just beat Match the pairs in ${moveCount} moves!\n${emojiBoard}`

  if (Platform.OS === "web") {
    await Clipboard.setStringAsync(message)

    alert(`The following message was copied to your clipboard. \n\n${message}`)
    return
  }

  return await Share.share({
    message,
  })
}
```

And there we have it! A function to share the game result that works across multiple platforms, even when the same APIs aren't supported on each platform.

![iOS, Android, and the web showing their respective version of the share dialog](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w3ce6uro83alen2rybtj.png)