Open AareFabrik opened 1 month ago
are you using react-native and react-native-web or just pure next.js?
it's been a while since last time I worked with next, so I'm not familiar with app router yet, but i think i got it working. I'll update the readme with examples and will update rnmq with some helpers like RNMQProvider to make this easier when I have some time, but in the meantime to get app router working this is what needs to be done:
if using react-native + react-native-web + rnmq:
need to update aliases and extensions in next.config:
const nextConfig = {
...
webpack(config) {
config.resolve.alias = {
...(config.resolve.alias || {}),
"react-native$": "react-native-web",
"react-native/Libraries/EventEmitter/RCTDeviceEventEmitter$":
"react-native-web/dist/vendor/react-native/NativeEventEmitter/RCTDeviceEventEmitter",
"react-native/Libraries/vendor/emitter/EventEmitter$":
"react-native-web/dist/vendor/react-native/emitter/EventEmitter",
"react-native/Libraries/EventEmitter/NativeEventEmitter$":
"react-native-web/dist/vendor/react-native/NativeEventEmitter",
};
config.resolve.extensions = [
".web.js",
".web.jsx",
".web.ts",
".web.tsx",
...(config.resolve?.extensions ?? []),
];
return config;
},
...
}
create or update globals.css with:
html,
body,
#__next {
width: 100%;
/* To smooth any scrolling behavior */
-webkit-overflow-scrolling: touch;
margin: 0px;
padding: 0px;
/* Allows content to fill the viewport and go beyond the bottom */
min-height: 100%;
}
#__next {
flex-shrink: 0;
flex-basis: auto;
flex-direction: column;
flex-grow: 1;
display: flex;
flex: 1;
}
html {
scroll-behavior: smooth;
/* Prevent text size change on orientation change https://gist.github.com/tfausak/2222823#file-ios-8-web-app-html-L138 */
-webkit-text-size-adjust: 100%;
height: 100%;
}
body {
display: flex;
/* Allows you to scroll below the viewport; default value is visible */
overflow-y: auto;
overscroll-behavior-y: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-ms-overflow-style: scrollbar;
}
create RNMQProvider.tsx:
"use client";
import { useServerInsertedHTML } from "next/navigation";
import { StyleSheet } from "react-native";
import { flush } from "react-native-media-query";
export function RNMQProvider({ children }: { children: React.ReactNode }) {
useServerInsertedHTML(() => {
const style = flush();
const sheet = StyleSheet.getSheet();
return (
<>
{style}
<style
dangerouslySetInnerHTML={{ __html: sheet.textContent }}
id={sheet.id}
/>
</>
);
});
return <>{children}</>;
}
then import RNMQProvider and globals.css into layout.tsx and wrap children with it:
...
import "./globals.css";
import { RNMQProvider } from "./RNMQProvider";
...
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body>
<RNMQProvider>{children}</RNMQProvider>
</body>
</html>
);
}
then use RNMQ as usual:
"use client";
import StyleSheet from "react-native-media-query";
import { Text, View } from "react-native";
const { ids, styles } = StyleSheet.create({
example: {
backgroundColor: "green",
borderRadius: 5,
"@media (max-width: 1600px) and (min-width: 800px)": {
backgroundColor: "red",
borderRadius: 10,
},
"@media (max-width: 800px)": {
backgroundColor: "blue",
borderRadius: 15,
},
},
});
export default function IndexPage() {
return (
<View>
<Text style={styles.example} dataSet={{ media: ids.example }}>
Hello, world!
</Text>
</View>
);
}
not using rn and rn-web makes this a bit easier:
globals.css from above is not needed
RNMQProvider.tsx looks like this:
"use client";
import { useServerInsertedHTML } from "next/navigation";
import { flush } from "react-native-media-query";
export function RNMQProvider({ children }: { children: React.ReactNode }) {
useServerInsertedHTML(() => {
const style = flush();
return style;
});
return <>{children}</>;
}
and then use it:
"use client";
import StyleSheet from "react-native-media-query";
const { ids, styles } = StyleSheet.create({
example: {
backgroundColor: "green",
borderRadius: 5,
"@media (max-width: 1600px) and (min-width: 800px)": {
backgroundColor: "red",
borderRadius: 10,
},
"@media (max-width: 800px)": {
backgroundColor: "blue",
borderRadius: 15,
},
},
});
export default function IndexPage() {
return (
<div>
<p style={styles.example} data-media={ids.example}>
Hello, world!
</p>
</div>
);
}
let me know if this makes sense. I will look into supporting styling without 'use client', but if you're using react-native-web then I don't think it supports running without 'use client' directive anyway
Hello
Nice package, it is really useful. But unfortunately I was not able to use it for the new app router for nextjs.
Is there a possibility to make this work?