Ensuring Content Stays Within a Mobile Device's Safe Area
Tags: reactnative
Published: 2021-12-04 10:08:22

---
title: Ensuring Content Stays Within a Mobile Device's Safe Area
published: true
date: 2021-12-04 00:00:00 UTC
tags: reactnative
description: Using the react-native-safe-area-context package
canonical_url: https://bionicjulia.com/blog/ensuring-content-stays-within-mobile-device-safe-area-react-native
---

For this week's blog post, I want to give a shoutout to a handy little package called the [react-native-safe-area-context](https://github.com/th3rdwave/react-native-safe-area-context#optimization). When I first started developing for mobile with React Native, I was let loose on an existing code base, and so, never really had to think about how to ensure that any content displayed to users falls within the mobile device's "safe area".

But what does "safe area" mean really? React Native actually comes with a [`SafeAreaView` component](https://reactnative.dev/docs/safeareaview) whose purpose is to "render content within the safe area boundaries of a device".

> `SafeAreaView` renders nested content and automatically applies padding to reflect the portion of the view that is not covered by navigation bars, tab bars, toolbars, and other ancestor views. Moreover, and most importantly, Safe Area's paddings reflect the physical limitation of the screen, such as rounded corners or camera notches (i.e. the sensor housing area on iPhone X).

As you can imagine, in today's world where there are hundreds, if not thousands, of devices available, this is an absolute must, only to be ignored at your own peril. ☠️ Unfortunately, as of React Native v0.66, `SafeAreaView` is only applicable to iOS devices with iOS version 11+. So what's a React Native developer to do?

Enter `react-native-safe-area-context`! This is a package that introduces itself as "a flexible way to handle safe area, [that] also works on Android and Web!". Hurrah! Because our app needs to cater for Android users in particular, this is a package we've implemented in our code base with good success.

Here's a quick run-through of how to set it up.

1. Wrap your root component, in the `SafeAreaProvider`.

```tsx
import { SafeAreaProvider } from 'react-native-safe-area-context'

function App() {
  return <SafeAreaProvider>...</SafeAreaProvider>
}
```

1. Wrap the contents of your screen component in a `SafeAreaView`. In my case, I use a `Screen` component which serves as the basis for all the screens across the app. This is therefore where I chose to add the `SafeAreaView`. Note that this component accepts all props that a React Native `View` component would accept.

```tsx
import { SafeAreaView } from 'react-native-safe-area-context'

export function Screen(props) {
  return (
    <SafeAreaView style={{ flex: 1, backgroundColor: 'red' }}>
      <View style={{ flex: 1, backgroundColor: 'blue' }} />
    </SafeAreaView>
  )
}
```

And that's pretty much it really! There are more settings and API features you can play with, so check out their [GitHub page](https://github.com/th3rdwave/react-native-safe-area-context) for more info.

Now, the reason this all came to my attention recently was because I was having some spacing issues upon deciding to implement a tab navigator, for the first time, in the app. This tab navigator will sit at the bottom of the screen, and I had set it so that screen content would not "flow beneath" the tab, but instead stop above the tab. (If you use React Navigation bottom tabs navigator, and you're curious about the setting, it's [this one](https://reactnavigation.org/docs/bottom-tab-navigator#tabbarstyle).)

The `SafeAreaView` sets the margins nicely for all edges of the mobile screen... apart from the bottom edge. Why? `SafeAreaView` (of course) does not know that there's now a tab navigator in between the device's edge and the bottom of the screen's content, therefore resulting in a large gap between the end of the screen's content and the top of the tab navigator.

Thankfully, there's a nice easy fix that comes with the `react-native-safe-area-context` package, through the use of the `edges` prop. This tells `SafeAreaView` which edges you want to apply the safe area margins to, which in my case, meant **excluding** the "bottom" edge. However, because I use the `Screen` component as the basis for all my screens, I had to be sure this only applied to screens that sit **within** the tab navigator view.

```tsx
import { SafeAreaView } from 'react-native-safe-area-context'

const edgesTabView = ['right', 'top', 'left']

export function Screen(props) {
  return (
    <SafeAreaView style={{ flex: 1, backgroundColor: 'red' }} edges={props.inTabView ? edgesTabView : undefined}>
      <View style={{ flex: 1, backgroundColor: 'blue' }} />
    </SafeAreaView>
  )
}
```

As you can see here, whenever I use my `Screen` component, I can set an `inTabView` prop, where if `true`, will only set safe area insets for the right, top and left screen edges. If `edges` is not defined, it defaults to all edges.

Continue the discussion at https://bionicjulia.com, [Twitter](https://twitter.com/bionicjulia) or [Instagram @bionicjulia](https://instagram.com/bionicjulia).