RORK LABJP
TOOLING — Rork's developer repos keep moving: rork-xcode was updated on July 16, rork-device on July 15, and rork-plist on July 13OPUS46 — Claude Opus 4.6 is live in Rork, and Rork Max is built to assemble apps on top of Claude CodeSIM — A cloud iOS simulator runs in the browser, with one click to install on a device and two clicks to publish to the App StoreMAX — Rork Max emits pure Swift rather than React Native, reaching iPhone, iPad, Apple Watch, Apple TV, Vision Pro, and even iMessageNATIVE — That opens up HealthKit, ARKit and LiDAR, NFC, Dynamic Island, Live Activities, 3D through Metal, and on-device inference with Core MLSEED — Rork raised a $15M seed led by Left Lane Capital, with Peak XV and a16z Speedrun joining the roundTOOLING — Rork's developer repos keep moving: rork-xcode was updated on July 16, rork-device on July 15, and rork-plist on July 13OPUS46 — Claude Opus 4.6 is live in Rork, and Rork Max is built to assemble apps on top of Claude CodeSIM — A cloud iOS simulator runs in the browser, with one click to install on a device and two clicks to publish to the App StoreMAX — Rork Max emits pure Swift rather than React Native, reaching iPhone, iPad, Apple Watch, Apple TV, Vision Pro, and even iMessageNATIVE — That opens up HealthKit, ARKit and LiDAR, NFC, Dynamic Island, Live Activities, 3D through Metal, and on-device inference with Core MLSEED — Rork raised a $15M seed led by Left Lane Capital, with Peak XV and a16z Speedrun joining the round
Articles/Dev Tools
Dev Tools/2026-04-21Intermediate

Fixing Safe Area & Notch Display Issues in Rork Apps

Why content in Rork-generated apps clips behind the iPhone notch and home indicator, and the SafeAreaView / useSafeAreaInsets patterns that actually fix it.

Rork515Safe AreaReact Native209iOS109Android43UI10

There's a moment when you first run a Rork-generated prototype on a real iPhone 15 Pro and something feels off. The header you placed at the top is cutting into the notch. The tab bar at the bottom is being eaten by the home indicator. Everything looked fine in Rork's web preview — but the moment you shipped to TestFlight, the layout fell apart. The first time I pushed a Rork app to TestFlight, I spent a solid half hour staring at this exact problem.

This isn't a Rork-specific bug. It's a layout issue that hits every React Native / Expo app when the developer doesn't account for safe areas, and Rork's generated code tends to include only minimal safe area handling — which makes the problem surface quickly. In this article I'll walk through why the problem shows up, and the exact patterns you can drop into your Rork code to fix it.

Why Rork's preview doesn't catch this

Rork's web preview renders the app into a flat rectangular frame. There's no notch, no Dynamic Island, no home indicator, no Android gesture bar. Content that sits flush against the edge of the preview looks clean — but the moment it hits a real device, it collides with system UI regions like these:

  • The iPhone X-and-later notch / Dynamic Island (roughly 44–59pt at the top)
  • The iPhone home indicator (about 34pt at the bottom)
  • Android's status bar (about 24dp at the top)
  • Android's navigation bar (about 48dp, though gesture nav differs)

React Native gives you two tools to keep content out of these regions: SafeAreaView and useSafeAreaInsets. Rork's generated code often has one but not the other, or places them in a nesting order that silently breaks them.

The minimal fix: wrap in SafeAreaView

The simplest fix is wrapping the screen in SafeAreaView. For a plain list screen with no header or footer, that's all you need.

import { SafeAreaView } from "react-native-safe-area-context";
import { ScrollView, View, Text, StyleSheet } from "react-native";
 
export default function ArticleList() {
  return (
    <SafeAreaView style={styles.safe} edges={["top", "bottom"]}>
      <ScrollView>
        <View style={styles.header}>
          <Text style={styles.title}>Articles</Text>
        </View>
        {/* list items */}
      </ScrollView>
    </SafeAreaView>
  );
}
 
const styles = StyleSheet.create({
  safe: { flex: 1, backgroundColor: "#fff" },
  header: { padding: 16 },
  title: { fontSize: 22, fontWeight: "700" },
});

The critical detail: import SafeAreaView from react-native-safe-area-context, not from react-native itself. The React Native built-in version is iOS-only and does nothing on Android. Expo projects ship with react-native-safe-area-context by default, so the import works out of the box.

The edges prop lets you pick which sides to apply. On screens with a custom bottom tab bar, use edges={["top"]} and handle the bottom manually — which brings us to the next pattern.

For screens with tab bars or custom headers: useSafeAreaInsets

Screens with a tab bar or a custom header can't rely on SafeAreaView alone, because the content region and the bar region need different padding math. Use useSafeAreaInsets to read the raw numbers and apply them yourself.

import { useSafeAreaInsets } from "react-native-safe-area-context";
import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
 
export default function TabBarLayout({ children }: { children: React.ReactNode }) {
  const insets = useSafeAreaInsets();
 
  return (
    <View style={styles.container}>
      {/* Custom header: add notch padding */}
      <View style={[styles.header, { paddingTop: insets.top + 8 }]}>
        <Text style={styles.headerTitle}>Home</Text>
      </View>
 
      {/* Content region */}
      <View style={styles.content}>{children}</View>
 
      {/* Custom tab bar: add home indicator padding */}
      <View style={[styles.tabBar, { paddingBottom: insets.bottom + 8 }]}>
        <TouchableOpacity style={styles.tab}>
          <Text>Home</Text>
        </TouchableOpacity>
        <TouchableOpacity style={styles.tab}>
          <Text>Profile</Text>
        </TouchableOpacity>
      </View>
    </View>
  );
}
 
const styles = StyleSheet.create({
  container: { flex: 1, backgroundColor: "#fff" },
  header: {
    paddingHorizontal: 16,
    paddingBottom: 12,
    borderBottomWidth: 1,
    borderBottomColor: "#eee",
  },
  headerTitle: { fontSize: 18, fontWeight: "600" },
  content: { flex: 1 },
  tabBar: {
    flexDirection: "row",
    paddingTop: 8,
    paddingHorizontal: 16,
    borderTopWidth: 1,
    borderTopColor: "#eee",
  },
  tab: { flex: 1, alignItems: "center" },
});

Expected behaviour: on iPhone 15 Pro the header gets roughly 59pt of top padding and the tab bar gets roughly 34pt of bottom padding. On iPhone SE the top is about 20pt and the bottom drops to 0. Android gets the status bar and nav bar heights reflected automatically.

Common gotchas

SafeAreaProvider isn't wrapping your app

useSafeAreaInsets returns zeroes for everything if it isn't inside a SafeAreaProvider. Rork-generated code sometimes ships without it in _layout.tsx or App.tsx. Wrap your root like this:

// app/_layout.tsx (Expo Router) or App.tsx
import { SafeAreaProvider } from "react-native-safe-area-context";
import { Stack } from "expo-router";
 
export default function RootLayout() {
  return (
    <SafeAreaProvider>
      <Stack />
    </SafeAreaProvider>
  );
}

Background color shifts visibly at the notch

If the area outside your SafeAreaView has a different colour than the inside, you get a visible seam around the notch. When you want a header colour to bleed all the way up behind the notch, skip SafeAreaView and use a plain View as the root, then apply paddingTop: insets.top inside. The colour extends edge to edge and the layout still clears the notch.

SafeAreaView inside ScrollView

SafeAreaView is meant to be a screen-level wrapper. Putting it inside a ScrollView doesn't do what you'd expect. Put the ScrollView inside the SafeAreaView instead. If you want scroll content to extend to the bottom edge with proper spacing, the idiomatic pattern is contentContainerStyle={{ paddingBottom: insets.bottom }}.

Insets read as zero inside a modal

Inside an iOS modal (presentation: "modal"), the modal's own rounded top avoids the notch, so insets.top ends up near zero by design. The home indicator is still there though, so keep using insets.bottom for the bottom padding inside modal screens.

Testing on a real device

None of this shows up in Rork's web preview, so you have to validate on hardware or in Expo Go. The fastest loop is to export your Rork project to GitHub and open it in Expo Go.

  1. Export to GitHub from the top-right of the Rork editor
  2. Run npx expo start locally
  3. Scan the QR code with Expo Go on your iPhone
  4. Check three devices: iPhone 15 Pro, iPhone SE, and any Android device

When it looks right on a notched device and an unnotched device, you're done. Expo Go has a "Device Frame" toggle that makes it easy to flip between device profiles without leaving the preview.

This topic overlaps a lot with other Rork layout issues. If iOS and Android are diverging, the iOS vs Android behavior difference guide is worth a read. For keyboard overlapping input fields, see the keyboard avoidance fix guide. And if you're hitting responsive layout issues in general, the layout and responsive design troubleshooting guide pairs well with this one.


Open your app's top-level _layout.tsx first and check whether SafeAreaProvider is there. Adding it takes five minutes and kills more than half of these layout issues on its own. The rest you can mop up screen by screen with useSafeAreaInsets, and your Rork app will finally look as clean on real devices as it did in the preview.

Share

Thank You for Reading

Rork Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

Dev Tools2026-05-02
Why StatusBar Colors Won't Apply in Rork — and How to Fix It
A practical, case-by-case guide to fixing StatusBar color and style issues in Rork apps across iOS and Android, based on real shipping experience.
Dev Tools2026-04-24
Rork WebView Is Blank or Won't Load: 6 Causes to Check Before You Ship
Dropped a WebView into your Rork app and got a silent blank screen on device? Here's the checklist I run through, in the order that catches the most bugs first.
Dev Tools2026-04-18
Rork App Works on iOS but Breaks on Android: A Practical Guide to Fixing Platform Differences
Troubleshoot Rork apps that work on iOS but break on Android. Covers shadows, fonts, permissions, keyboard, and status bar with code examples.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →