I recently decided to migrate to NextJs, but I'm having a few problems doing so. I have coded an ExpressJs API and now I want to use it as a Custom NextJs Server, as it says in the Docs, but I can't make it work
Here's my server.ts file (I'm using Typescript)
///<reference path="../@types/index.d.ts"/>
import express from "express";
import next from "next";
// Rest of the imports (I removed to make the code shorter here)
import api from "./api";
const dev = process.env.NODE_ENV !== "production";
const app = next({ dev });
const handle = app.getRequestHandler();
const port = process.env.PORT || 3000;
require("dotenv").config();
app
.prepare()
.then(() => {
const server = express();
// All these following middlewares are imported previously
server.use(logger("dev"));
server.use(cors());
server.use(compression());
server.use(express.json());
server.use(express.urlencoded({ extended: false }));
server.use(cookieParser());
server.use(NoCache);
server.use("/api", auth.userHeader(), API); // My routes
server.get("*", (req, res, next) => handle(req, res)); // NextJs Handle
server.use(ErrorHandler);
server.listen(port, () => {
console.log(`Server Listening to port ${port}`);
});
})
.catch((ex) => {
console.error(ex.stack);
process.exit(1);
});
export default app;
I made a very simple app to test it (only a link to a login page)
When I run the project with next my application [works as expected and styles are applied][2], but obviously the ExpressJs API doesn't. However, when I run the server.ts file, the API works as expected (all endpoints are functional) and I get next's compiled successfully message, but [the page comes blank][3] given to a style applied by next automatically and also no CSS is loaded into the application (I added a style to the body tag on globals.scss to set the display of it to block !important, so it would overwrite the style that makes the page not show).
Here's my _app.tsx file
import { AuthProvider } from "../context/auth";
import "../styles/globals.scss";
function MyApp({ Component, pageProps }) {
return (
<AuthProvider>
<Component {...pageProps} />
</AuthProvider>
);
}
export default MyApp;
and you can see I import the globals.scss right at the top
Here's my _document.tsx file
import Document, { Html, Head, Main, NextScript } from "next/document";
class NextDocument extends Document {
render() {
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
export default NextDocument;
Here's my next.config.js file
module.exports = {
publicRuntimeConfig: {
// Will be available on both server and client
API_URL: process.env.API_URL,
},
};
Is there anything I'm missing? I followed the documentation and a few videos I watched, but still no progress
Thanks in advance. Please let me know if you need any other information.
UPDATE
After a few tests, I realized that when I remove typescript, everything works perfectly. I still don't know how to solve it and I don't want to lose all the benefits from typescript
My tsconfig.json
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "CommonJS",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve"
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "pages/a.js", "pages/b.js", "pages/index.js", "server.js"],
"exclude": ["node_modules"]
}