How to Setup React Native Web in a Remix project

I assume you’re here because you want to know how to set up React Native Web in your Remix project. Well, you’re lucky, I had to do this a few days ago, and I haven’t run into trouble with it yet, so here’s a tutorial about it:

Let’s get started!

The…


This content originally appeared on DEV Community and was authored by Horus Lugo

I assume you're here because you want to know how to set up React Native Web in your Remix project. Well, you're lucky, I had to do this a few days ago, and I haven't run into trouble with it yet, so here's a tutorial about it:

Let's get started!

The result of this tutorial is also available as a GitHub repository that you can just clone to get started with your project: https://github.com/HorusGoul/remix-react-native-web-starter

1. Installing the react-native-web package

The first thing you have to do is install the react-native-web package. However, since we can't customize our build process because Remix doesn't allow it yet, we'll need to use a package manager that will enable you to install a package with an alias. In this case, I decided to use pnpm.

$ pnpm add react-native@npm:react-native-web

Then, the types if you're using TypeScript. Note that not all types will be correct for a React Native Web project, but that's out of the scope of this tutorial.

$ pnpm add --save-dev @types/react-native

2. React Native Web Styles

React Native Web has its own way of handling styles, and for SSR and hydration, they give you a stylesheet element that you have to place in the <head> of your page.

We'll pass that stylesheet element to our Root using the Context API. Let's do that by creating a rn-styles.tsx file inside the app folder. Here's the content for that file:

import { createContext, Fragment, useContext } from "react";

export const ReactNativeStylesContext = createContext<
  React.ReactElement<unknown>
>(<Fragment />);

export function useReactNativeStyles() {
  return useContext(ReactNativeStylesContext);
}

Now, let's move to the app/root.tsx file. We'll now use the useReactNativeStyles() hook and put the stylesElement inside the <head>. Also, we'll wrap the <Outlet /> component with a View with a few properties to match the React Native Web behavior.

...

import { useReactNativeStyles } from "./rn-styles";
import { View, StyleSheet } from "react-native";

...

export default function App() {
  const stylesElement = useReactNativeStyles();

  return (
    <html lang="en">
      <head>
        ...

        {stylesElement}
      </head>
      <body>
        ...

        <View pointerEvents="box-none" style={styles.appContainer}>
          <Outlet />
        </View>

        ...
      </body>
    </html>
  );
}

const styles = StyleSheet.create({
  appContainer: {
    flex: 1,
  },
});

We also need to add a global stylesheet to Remix that contains the following.

html, body {
  height: 100%;
}

body {
  display: flex;
}

Take a look at the Remix Docs about Stylesheets if you don't know how to add CSS in a Remix project.

3. SSR and Hydration

Assuming you haven't modified the app/entry.client.tsx file, just replace its contents with the following:

import { RemixBrowser } from "remix";
import { hydrate } from "react-dom";
import { AppRegistry } from "react-native";
import { ReactNativeStylesContext } from "./rn-styles";

const App = () => <RemixBrowser />;

AppRegistry.registerComponent("App", () => App);

// @ts-ignore
const { getStyleElement } = AppRegistry.getApplication("App");

hydrate(
  <ReactNativeStylesContext.Provider value={getStyleElement()}>
    <App />
  </ReactNativeStylesContext.Provider>,
  document
);

What's going on with that code? We're using React Native Web AppRegistry to get the initial styles for the app and avoid hydration from failing.

Now, let's move to the app/entry.server.tsx file, where we'll do a similar thing. Take a look at the code:

import { renderToString } from "react-dom/server";
import { RemixServer, type EntryContext } from "remix";
import { AppRegistry } from "react-native";
import { ReactNativeStylesContext } from "./rn-styles";

export default function handleRequest(
  request: Request,
  responseStatusCode: number,
  responseHeaders: Headers,
  remixContext: EntryContext
) {
  const App = () => <RemixServer context={remixContext} url={request.url} />;

  AppRegistry.registerComponent("App", () => App);

  // @ts-ignore
  const { getStyleElement } = AppRegistry.getApplication("App", {});

  const page = (
    <ReactNativeStylesContext.Provider value={getStyleElement()}>
      <App />
    </ReactNativeStylesContext.Provider>
  );

  const markup = renderToString(page);

  responseHeaders.set("Content-Type", "text/html");

  return new Response("<!DOCTYPE html>" + markup, {
    status: responseStatusCode,
    headers: responseHeaders,
  });
}

Again, we're using the AppRegistry to get the app styles and then pass them to the remix app using the ReactNativeStylesContext.

4. Using React Native Web components

One last thing you could do if you're doing this in a new project is to go ahead and replace your app/routes/index.tsx with the following:

import { Text, View } from "react-native";

export default function Index() {
  return (
    <View>
      <Text>Hello, world!</Text>
    </View>
  );
}

Then do pnpm dev and open your project in the browser to see your first Remix route rendered with React Native Web components!

I hope you liked this article! Don't forget to follow me on Twitter if you want to know when I publish something new about web development: @HorusGoul


This content originally appeared on DEV Community and was authored by Horus Lugo


Print Share Comment Cite Upload Translate Updates
APA

Horus Lugo | Sciencx (2022-02-07T19:18:58+00:00) How to Setup React Native Web in a Remix project. Retrieved from https://www.scien.cx/2022/02/07/how-to-setup-react-native-web-in-a-remix-project/

MLA
" » How to Setup React Native Web in a Remix project." Horus Lugo | Sciencx - Monday February 7, 2022, https://www.scien.cx/2022/02/07/how-to-setup-react-native-web-in-a-remix-project/
HARVARD
Horus Lugo | Sciencx Monday February 7, 2022 » How to Setup React Native Web in a Remix project., viewed ,<https://www.scien.cx/2022/02/07/how-to-setup-react-native-web-in-a-remix-project/>
VANCOUVER
Horus Lugo | Sciencx - » How to Setup React Native Web in a Remix project. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2022/02/07/how-to-setup-react-native-web-in-a-remix-project/
CHICAGO
" » How to Setup React Native Web in a Remix project." Horus Lugo | Sciencx - Accessed . https://www.scien.cx/2022/02/07/how-to-setup-react-native-web-in-a-remix-project/
IEEE
" » How to Setup React Native Web in a Remix project." Horus Lugo | Sciencx [Online]. Available: https://www.scien.cx/2022/02/07/how-to-setup-react-native-web-in-a-remix-project/. [Accessed: ]
rf:citation
» How to Setup React Native Web in a Remix project | Horus Lugo | Sciencx | https://www.scien.cx/2022/02/07/how-to-setup-react-native-web-in-a-remix-project/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.