1

I have a very simple Next.js app that uses app router and i18n and everything works good locally, but as soon as I deploy it to IIS, I get warnings in console for both js and css files: The script from “https://some-domain.eu/_next/static/chunks/app/%5Blng%5D/page-ff2a904e6ac40466.js” was loaded even though its MIME type (“text/html”) is not a valid JavaScript MIME type. I've been stuck on this problem for 2 days now without a solution in sight. Please, if anyone knows how to fix this, let me know, all advices are much appreciated!

here is my web.config

<configuration>
  <system.webServer>
  
    <handlers>
      <add name="iisnode" path="server.js" verb="*" modules="iisnode" />
      <add name="StaticFileHandler" path="*" verb="*" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Read" />
    </handlers>

    <rewrite>
      <rules>
        <rule name="HTTPS Redirect" stopProcessing="true">
            <match url="(.*)" />
            <conditions>
                <add input="{HTTPS}" pattern="^OFF$" />
            </conditions>
            <action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" appendQueryString="false" />
        </rule>

        <rule name="StaticContent" stopProcessing="true">
          <match url=".*" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" />
            <add input="{REQUEST_URI}" matchType="Pattern" pattern="^/public/" negate="true" />
          </conditions>
          <action type="Rewrite" url="/public{REQUEST_URI}" />
        </rule>

        <rule name="DynamicContent">
          <conditions>
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True" />
          </conditions>
          <action type="Rewrite" url="server.js" />
        </rule>
      </rules>
    </rewrite>
    
     <!-- 'bin' directory has no special meaning in node.js and apps can be placed in it -->
    <security>
      <requestFiltering>
        <hiddenSegments>
          <add segment="node_modules"/>
        </hiddenSegments>
      </requestFiltering>
    </security>

    <!-- Make sure error responses are left untouched -->
    <httpErrors existingResponse="PassThrough" />
    <iisnode node_env="production" />

    </system.webServer>
</configuration>

and my server.js code

const { createServer } = require('http');
const { parse } = require('url');
const next = require('next');
const { NextResponse } = require('next/server');
const dev = process.env.NODE_ENV !== 'production';
const hostname = 'localhost';
const port = process.env.PORT || 3000;
const acceptLanguage =  require("accept-language");

// when using middleware `hostname` and `port` must be provided below
const app = next({ dev, hostname, port });
const handle = app.getRequestHandler();

const fallbackLng = "en";
const languages = [fallbackLng, "hr"];
acceptLanguage.languages(languages);


function getLocale(request) {
    const acceptLanguageHeader = request.headers.get("Accept-Language");
  
    if (!acceptLanguageHeader) {
      return fallbackLng;
    }
  
    // Split the Accept-Language header into an array of language tags
    const acceptedLangs = acceptLanguageHeader
      .split(",")
      .map((language) => language.trim().split(";")[0]);

  
    // Find the best match between the supported locales and the client's preferred languages
    const locale = acceptedLangs.find((lang) => languages.includes(lang)) || fallbackLng;
  
    return locale;
  }

  const config = {
    // matcher: '/:lng*'
    matcher: ["/((?!api|_next/static|_next/image|assets|favicon.ico|sw.js).*)"],
  };
  app.prepare().then(() => {
    createServer(async (req, res) => {

        // Emergent bug in Next.js: doesn't deal wll with brackets in 
        // URL when iisnode or other reverse proxy is in the middle.
        // See https://github.com/vercel/next.js/issues/54325
        let reqUrl = req.url
            .replace(/\[/g, '%5B')
            .replace(/\]/g, '%5D');
            console.log(`>>> ` + reqUrl);

        try { 
          if (req.nextUrl.startsWith("/_next") || req.nextUrl.startsWith("/assets/")) {
            return NextResponse.next();
          } else {
            const { pathname, origin } = req.nextUrl
            const pathnameHasLocale = languages.some(
              (locale) => req.nextUrl.startsWith(`/${locale}/`) || req.nextUrl === `/${locale}`
            )
      
            if (!pathnameHasLocale) {
              // get locale
              const locale = getLocale(req)
        
              //check if user is on root and redirect to default locale
              if (pathname === '/') {
                const redirectPath = `${origin}/${locale}`;
                return NextResponse.redirect(redirectPath);
              } else {
                if (config.matcher.some((pattern) => new RegExp(pattern).test(pathname))) {
                  return;
                }           
                console.log("redirect: ", `${origin}/${locale}${pathname}`);
                return NextResponse.redirect(`${origin}/${locale}${pathname}`);
              }
            
            }
          }
        } catch (err) {
            console.error('Error occurred handling', reqUrl, err);
            if (err.code === 'ENOENT') {
              // Handle 404 errors
              return app.render(req, res, '/404', {
                statusCode: 404,
                title: 'Page Not Found',
              });
            } else {
              // Handle other errors (500)
              return app.render(req, res, '/500', {
                statusCode: 500,
                title: 'Internal Server Error',
              });
            }
        }
    })
    .listen(port, (err) => {
        if (err) throw err;
        console.log(`> Ready on http://${hostname}:${port}`);
    });
  });

I've tried to change web.config rules with adding mimeMap and setting mimeType to text/css for css and text/javascript for js, but that resulted in 500 error

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.