-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for nextjs 13 + with app router #16
Comments
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 |
@kasinskas it works perfectly fine as you wrote above, however when I try to build the next app I am getting an error:
In my babel I have
NOTE: all fine when I am running |
I just tried building project you shared with me a while ago (#17 (comment)), just replaced pages with app router and the setup exactly as described above and everything passed: Are you using styled-jsx? Looking into the styled-jsx/babel plugin code it seems to be looking for name attribute on style tag. This might be related - vercel/styled-jsx#843, so you can try using patch-package to add this or just add name attributes on style tags and see if that helps. |
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?
The text was updated successfully, but these errors were encountered: