Full codebase & folder structure can be seen in GitHub
Here is the Swagger related route (had to make it a standalone server)
// api/v1.ts
import express = require("express");
import swaggerJSDoc = require("swagger-jsdoc");
import swaggerUi = require("swagger-ui-express");
import packageJSON = require("../package.json");
import path = require("path");
const app = express();
app.use(express.json());
app.use(express.static(path.resolve(__dirname, "../", "public")));
const swaggerSpec = swaggerJSDoc({
swaggerDefinition: some_spec,
apis: ["api/*"]
});
const cssOpts = some_css_override;
app.use("/api/v1", swaggerUi.serve, swaggerUi.setup(swaggerSpec, cssOpts));
module.exports = app;
When I run vercel dev
(locally- localhost:3000/api/v1), I see documentation as expected:
However when I push my code to a branch which triggers a vercel build, I see the following:
Checking the console, I see:
DevTools failed to load source map: Could not parse content for https://colormaster-1unjfn63b-lbragile.vercel.app/api/v1/swagger-ui-bundle.js.map: Unexpected token < in JSON at position 1
DevTools failed to load source map: Could not parse content for https://colormaster-1unjfn63b-lbragile.vercel.app/api/v1/swagger-ui-standalone-preset.js.map: Unexpected token < in JSON at position 1
Even though they respond with 200
I understand that this has something to do with JSON.parse()
of HTML content, but not sure how to fix this. Any ideas?
I am facing the exact same problem of you, trying without success to deploy Swagger to Vercel with Express.
I did one step more, and now I'm seen an error in my console:
Refused to apply style from 'https://myurlishere.vercel.app/api-docs/swagger-ui.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
What I did was, adding a file routes.ts
import { Router } from 'express';
import LanguageController from './controller/LanguageController';
import WordController from './controller/WordController';
const routes = Router();
routes.get("/word", WordController.find);
routes.get("/word/:wordName/language/:languageId", WordController.findByWordAndLanguage);
routes.post("/word", WordController.create);
routes.get("/language", LanguageController.find);
export default routes;
And my server.ts looks like that:
import mongoose from 'mongoose';
import routes from './routes';
const express = require("express");
if (process.env.NODE_ENV !== 'production') {
require('dotenv').config();
}
const app = express();
const cors = require('cors');
mongoose.connect(process.env.MONGODB_URI || "", {
dbName: "WordsThatIKnowMongoDB"
})
.then(() => console.debug("Database connected!"))
.catch(err => { console.debug(err) });
app.use(express.json());
app.use(express.static("/api-docs"));
app.use(cors());
app.use(routes);
const swaggerUi = require('swagger-ui-express');
const swaggerDocument = require('./swagger.json');
routes.use('/api-docs', swaggerUi.serve);
routes.get('/api-docs', swaggerUi.setup(swaggerDocument));
app.listen(5000, () => {
console.debug("Running on port 5000.");
});
// Export the Express API
module.exports = app;
You will see in the file above that I changed app. to routes. like this:
routes.use('/api-docs', swaggerUi.serve);
routes.get('/api-docs', swaggerUi.setup(swaggerDocument));
I still can't solve this problem, but maybe this new error can help you find the solution. I'm also looking for that.
This is the code that solved my problem:
server.ts
import path from 'path';
import cors from 'cors';
import bodyParser from 'body-parser';
import mongoose from 'mongoose';
import routes from './routes';
const express = require("express");
const app = express();
const ROOT_FOLDER = path.join(__dirname, '..');
const SRC_FOLDER = path.join(ROOT_FOLDER, 'src');
// parse requests of content-type - application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }));
// parse requests of content-type - application/json
app.use(bodyParser.json());
app.use(cors());
app.use(routes);
if (process.env.NODE_ENV !== 'production') {
require('dotenv').config();
}
mongoose.connect(process.env.MONGODB_URI || "", {
dbName: "WordsThatIKnowMongoDB"
})
.then(() => console.debug("Database connected!"))
.catch(err => { console.debug(err) });
const swaggerUi = require('swagger-ui-express');
const swaggerDocument = require('./swagger.json');
const options = { customCssUrl: '/public/swagger-ui.css', customSiteTitle: "The Words That I Know API - Swagger" };
app.use('/public', express.static(path.join(SRC_FOLDER, 'public')));
app.use('/', swaggerUi.serve);
app.get('/', swaggerUi.setup(swaggerDocument, options));
app.listen(5000, () => {
console.debug("Running on port 5000.");
});
export default app;
Don't forget to put the styles from Swagger at '/public/swagger-ui.css'. Create a public
folder inside src
and include a swagger-ui.css
file. Inside of this, past swagger styles. You can find swagger styles using inspect
on browser, and going to source
tab. There you'll find the swagger-ui.css
file; remove the commented line after pasting the styles code.
If you prefer an easy way to get the styles code, get this file. https://github.com/deywersonp/ghibli-50-api/blob/main/src/public/css/swagger-ui.css