Search code examples
htmlrustnext.jscustom-error-pagestauri

Next.js app built with tauri does not show my 404 page


I have a next.js app with a file /app/not-found.tsx that works perfectly when using

cargo tauri dev

But when I compile the app with

cargo tauri build

or

cargo tauri build --debug

And navigate to a page that does not exist, I get rendered / (/app/page.tsx page) instead of /not-found but my url is still my.app/something-thats-not-found

Thats is my not-found.tsx file:

import {
  NotFoundButton,
  NotFoundContainer,
  NotFoundInfo,
} from "./styles/style";

const NotFound = () => {
  return (
    <NotFoundContainer>
      <NotFoundInfo>
        <h1>Not Found!</h1>
        <span>
          |、
          <br />
          (˚ˎ 。7
          <br />
          |、˜〵
          <br />
          じしˍ,)ノ
        </span>
      </NotFoundInfo>
      <NotFoundButton href="/">Go to home</NotFoundButton>
    </NotFoundContainer>
  );
};

export default function NotFoundCatchAllPage() {
  return <NotFound />;
}

I tried using this with NotFoundCatchAllPage() and without, but neither of them are working

tauri.conf.json:

{
  "build": {
    "beforeBuildCommand": "yarn build",
    "beforeDevCommand": "yarn dev",
    "devPath": "http://localhost:3000",
    "distDir": "../out"
  },
  "package": {
    "productName": "scribble",
    "version": "0.1.0"
  },
  "tauri": {
    "allowlist": {
      "all": false,
      "window": {
        "all": false,
        "close": true,
        "hide": true,
        "show": true,
        "maximize": true,
        "minimize": true,
        "unmaximize": true,
        "unminimize": true,
        "startDragging": true
      },
      "globalShortcut": {
        "all": true
      }
    },
    "bundle": {
      "active": true,
      "category": "DeveloperTool",
      "copyright": "",
      "deb": {
        "depends": []
      },
      "externalBin": [],
      "icon": [
        "icons/32x32.png",
        "icons/128x128.png",
        "icons/128x128@2x.png",
        "icons/icon.icns",
        "icons/icon.ico"
      ],
      "identifier": "com.scribble.dev",
      "longDescription": "",
      "macOS": {
        "entitlements": null,
        "exceptionDomain": "",
        "frameworks": [],
        "providerShortName": null,
        "signingIdentity": null
      },
      "resources": [],
      "shortDescription": "",
      "targets": "all",
      "windows": {
        "certificateThumbprint": null,
        "digestAlgorithm": "sha256",
        "timestampUrl": ""
      }
    },
    "security": {
      "csp": null
    },
    "updater": {
      "active": false
    },
    "windows": [
      {
        "fullscreen": false,
        "height": 600,
        "resizable": true,
        "title": "Scribble",
        "width": 800,
        "decorations": false
      }
    ]
  }
}

next.config.mjs:

/** @type {import('next').NextConfig} */
const nextConfig = {
  output: "export",
  compiler: {
    styledComponents: true,
  },
};

export default nextConfig;

Solution

  • NextJS relies on the 404 functionality in SSR mode. However when you package NextJS with Tauri, it just uses next export to package generated HTML and JS/CSS files (frontend only).

    So there's no NextJS (server) listening to the route changes.

    An easy solution would be to check if the requested page exists, and if it doesn't then redirect to a page of your choice.

    Oh, and do these checks in the client side in JS.