Reputation: 11
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
Upvotes: 1
Views: 274