2

I have already made a couple of pwa projects with Next JS but this time my site.webmanifest file does not load. When I look at the site.webmanifest in the browser I see it loads an html file with the starting page.

site.webmanifest:

{
  "name": "Task Manager",
  "short_name": "Task Manager",
  "description": "Application to save tasks",
  "display": "standalone",
  "start_url": "/",
  "icons": [
    {
      "src": "/icons/manifest-icon-192.maskable.png",
      "sizes": "192x192",
      "type": "image/png",
      "purpose": "any"
    },
    {
      "src": "/icons/manifest-icon-192.maskable.png",
      "sizes": "192x192",
      "type": "image/png",
      "purpose": "maskable"
    },
    {
      "src": "/icons/manifest-icon-512.maskable.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "any"
    },
    {
      "src": "/icons/manifest-icon-512.maskable.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "maskable"
    }
  ]
}

_middleware.tsx:

import { NextFetchEvent, NextRequest, NextResponse } from "next/server";

export function middleware(req: NextRequest, event: NextFetchEvent) {
  const jwt = req.cookies["jwt"];
  const urlArray: Array<string> = req.url.split("/");
  const baseUrl = `${urlArray[0]}//${urlArray[2]}`;
  if (req.url !== `${baseUrl}/login` && !jwt) {
    return NextResponse.redirect(`${baseUrl}/login`);
  }
}

link to manifest in _document.tsx

<link rel="manifest" href="/site.webmanifest" />

Error: Error on browser console

EDIT: I found out that this error happens because I use middleware to redirect to the login page when unauthenticated. But I still don't have a solution for this problem because I want to keep the middleware.

Talha Bayansar
  • 105
  • 1
  • 6

2 Answers2

4

Found the possible issue, i was having the same problem.

Next.js Middleware in the pages/_middleware.ts intercepts all the requests made, even those made to "public/images" or in your case /site.webmanifest

Your middleware tells that any request needs to have a jwt or be /login, so this middleware blocks the request made for /site.webmanifest

Still don't know if this is intended by Nextjs

if ((req.url !== `${baseUrl}/login` || req.url !== '/site.webmanifest') && !jwt) {
    return NextResponse.redirect(`${baseUrl}/login`);
}

Add something like private routes so the middleware only blocks request to them

const privatePaths = [/\/privateRoute2/,/\/privateRoute1\/*/]
const isPrivate = privatePaths.some(rx => rx.test(req.nextUrl.pathname));
if (isPrivate && !jwt) {
    const url = req.nextUrl.clone()
    url.pathname = '/authenticate'
    return NextResponse.redirect(url, 302);
}
return NextResponse.next()
0

Great answer @Santiago,

True, the nextjs middleware is new and is currently beta. It basically intercepts all your routes including your assets files served from the pubic/ folder. The simplest way to solve this is to actually make sure files with extensions are excluded (i.e .png, .jpg, .manifest, .json, etc)

const PUBLIC_FILE = /\.(.*)$/;
const isPublicFiles = PUBLIC_FILE.test(req.nextUrl.pathname);
if (!jwt && !isPublicFiles) {
  const token = await auth.currentUser?.getIdToken();
  const url = req.nextUrl.clone();
  url.pathname = '/login';

  return NextResponse.redirect(url);
}
return NextResponse.next();
unicdev
  • 300
  • 2
  • 7