Skip to content

[bug] NextJS app directory using router.push from next/navigation doesn't render page correctly. #6762

Closed

Description

@Royceb

Describe the bug

I was uncertain whether to open this in Tauri or NextJS, so I opened issues in both platforms.

While utilizing a NextJS application, version 13, and the experimental app directory, I encountered an issue where using router.push to navigate to a new page fails to render correctly. Although the navigation occurs successfully, the page only displays code as text instead of rendering the expected content. I have not found any console logs or errors related to this issue.

This problem only arises after building and running the application. Locally, everything seems to be functioning correctly.
See video:

Screen.Recording.2023-04-20.at.9.58.05.AM.mov

Screenshot:
image

Simple repro: https://github.com/Royceb/nextjs-app-dir-tauri-router-push-example

Reproduction

  1. Ran npx create-next-app@latest --experimental-app

  2. Set up Tauri

    2.1: Ran pnpm add -D @tauri-apps/cli

    2.2: Added tauri to package.json scripts. Ran pnpm tauri init.

  3. Updated next.config.js to use output: "export" for SSG (Static Generation).

  4. Made a simple page at app/examplePage/page.tsx

  5. Imported next/navigation in app/page.tsx and added a button that calls router.push('/examplePage').

  6. Ran pnpm tauri dev and clicked the button. The app navigated to the example page as expected and rendered it properly.

  7. Ran pnpm tauri build and opened the app. Clicked the button. The app did naviate to the example page, but it did not render it properly. The page rendered code as text instead of rendering the page.

Expected behavior

The page should render correctly like it does in dev.

Platform and versions

› OS: Mac OS 13.0.1 X64
  › Node.js: 18.12.1
  › npm: 8.19.2
  › pnpm: 7.24.2
  › yarn: 1.22.19
  › rustup: 1.25.1
  › rustc: 1.67.0
  › cargo: 1.67.0
  › Rust toolchain: stable-aarch64-apple-darwin

Stack trace

No response

Additional context

No response

Activity

  1. Royceb commented on Apr 21, 2023

    @Royceb
    Author

    Adding {forceOptimisticNavigation: true} to the router.push call fixed it.

    vercel/next.js#48642

  2. brillout commented on Apr 24, 2023

    @brillout

    Shameless plug: vite-plugin-ssr just added support for Tauri. Example: vite-plugin-ssr.com/tauri.

  3. jlarmstrongiv commented on Apr 24, 2023

    @jlarmstrongiv

    Hey @Royceb would you re-open this issue?

    Adding forceOptimisticNavigation is a temporary fix that degrades the user experience by forcing hard navigation.

    See vercel/next.js#48642 (comment)

  4. reopened this on Apr 24, 2023
  5. hopedope commented on May 10, 2023

    @hopedope

    Doesn't look like you can build any reasonable application using NextJS and Tauri. You can't have dynamic routes like /posts/1. Not even search params work, eg. posts?postId=1.

    Dynamic route issue: vercel/next.js#48022

    looks like I am moving to Vite 🎉

  6. jlarmstrongiv commented on May 11, 2023

    @jlarmstrongiv

    @hopedope looks like I’m moving to Astro

  7. reupen commented on Jun 1, 2023

    @reupen
    Contributor

    I've run into the same problem when using the Next.js app router. It seems to affect any kind of route navigation – I created another simple repro here:

    https://github.com/reupen/tauri-nextjs-repro

    This only happens in (release or debug) builds and not in dev mode (where the Next.js dev server is used).

    What happens is that the Next.js .txt metadata file for the route navigated to ends up being opened as a web page. So, in my example, subpage.txt is opened in the browser.

    I noticed (in a debug build) that the content type of the .txt file is reported as text/html in the developer tools, rather than text/plain. Not sure if that's the cause of the problem (or just a red herring).

    There's no problem when using another server to serve the static files and opening the site in a normal web browser. I'm on Ubuntu 22.04.

  8. reupen commented on Jun 1, 2023

    @reupen
    Contributor

    I did some further investigation. The issue is related to content types, though not in the way I expected. Here, when the web page loads, Next.js checks if the content-type header in the fetch() response for the .txt file (tauri://localhost/subpage.txt in my example) starts with text/plain:

    https://github.com/vercel/next.js/blob/38d9d2efee50e785f9fc707a9fcb349e49fa6dd5/packages/next/src/client/components/router-reducer/fetch-server-response.ts#L78-L93

    However, the content-type header is not set. In fact, there don't appear to be any headers set in the response at all. This causes Next.js to decide to navigate to the .txt file instead when the route is actually navigated to.

    I confirmed that to be the case by patching that line of code in Next.js to skip the content type check.

    Is there any particular reason why no response headers would be set in the response returned by fetch() in the browser?

    Thanks

  9. FabianLars commented on Jun 1, 2023

    @FabianLars
    Member

    @reupen Are you also on macOS? Or on Linux? In case you're on Linux, can you add the "linux-headers" feature flag to the tauri dependency in Cargo.toml and try again?

    Anyway, even if that brings back the headers, Tauri's "server" will fallback to an html mime type for txt files:

    pub fn parse_from_uri(uri: &str) -> MimeType {
    let suffix = uri.split('.').last();
    match suffix {
    Some("bin") => Self::OctetStream,
    Some("css" | "less" | "sass" | "styl") => Self::Css,
    Some("csv") => Self::Csv,
    Some("html") => Self::Html,
    Some("ico") => Self::Ico,
    Some("js") => Self::Js,
    Some("json") => Self::Json,
    Some("jsonld") => Self::Jsonld,
    Some("mjs") => Self::Js,
    Some("rtf") => Self::Rtf,
    Some("svg") => Self::Svg,
    Some("mp4") => Self::Mp4,
    // Assume HTML when a TLD is found for eg. `wry:://tauri.app` | `wry://hello.com`
    Some(_) => Self::Html,
    // https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
    // using octet stream according to this:
    None => Self::OctetStream,
    }
    }
    /// infer mimetype from content (or) URI if needed.
    pub fn parse(content: &[u8], uri: &str) -> String {
    let mime = if uri.ends_with(".svg") {
    // when reading svg, we can't use `infer`
    None
    } else {
    infer::get(content).map(|info| info.mime_type())
    };
    match mime {
    Some(mime) if mime == MIMETYPE_PLAIN => Self::parse_from_uri(uri).to_string(),
    None => Self::parse_from_uri(uri).to_string(),
    Some(mime) => mime.to_string(),
    }
    }
    }
    . Looks more like an oversight to me since text/plain should be the fallback for textual files according to mdn

  10. reupen commented on Jun 1, 2023

    @reupen
    Contributor

    @FabianLars I'm on Linux (Ubuntu 22.04). Did you mean the linux-protocol-headers feature? Can confirm that linux-protocol-headers + patching that bit of Tauri's code fixes the problem 🎉

    (I actually first tried patching that before I started digging into what was happening in Next.js...)

  11. FabianLars commented on Jun 1, 2023

    @FabianLars
    Member

    whoops, yeah that flag. i had Wry's flag in mind, sorry 😅

  12. nielsdB97 commented on Jun 9, 2023

    @nielsdB97

    Thanks everyone for your efforts, I'm now also looking to use Tauri combined with NextJS which should be a killer combo 😄

    @reupen am I correct in understanding that your PR should have fixed this issue with NextJS App Router builds not working? That would be fantastic, as I'm running into this problem now as well.
    @FabianLars could we get some sort of estimation on when this fix will get released?

  13. reupen commented on Jun 9, 2023

    @reupen
    Contributor

    @nielsdB97 I know it fixes Linux (with features = ["linux-protocol-headers"] for tauri in your Cargo.toml), and also Windows. I don't have access to macOS to test there.

  14. FabianLars commented on Jun 9, 2023

    @FabianLars
    Member

    could we get some sort of estimation on when this fix will get released?

    Pretty soon, what i heard is that there aren't that many things left we want to get into 1.4 so after the last few things are in only the audit is left. I'm a bit out of the loop so i don't want to say something like "probably around 2 weeks" 🤷

    Afaik there is no patch for 1.3 planned though.

  15. nielsdB97 commented on Jun 14, 2023

    @nielsdB97

    @reupen I can confirm it works on MacOS as well! 🎉
    @FabianLars a patch release would be great since this is quite a blocker for everyone starting a new project, following the Tauri NextJS guide. However, I understand this is a more intricate process considering audits and all.

    Thanks again both!

  16. FabianLars commented on Jun 14, 2023

    @FabianLars
    Member

    How about we just release v1.4 right now? 👀 Would that work for you too?

  17. FabianLars commented on Jun 14, 2023

    @FabianLars
    Member

    btw, closing this since the pr was merged (normally issues are autoclosed by github anyway)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions