scottie1984 / swagger-ui-express

Adds middleware to your express app to serve the Swagger UI bound to your Swagger document. This acts as living documentation for your API hosted from within your app.
MIT License
1.41k stars 225 forks source link

swagger-ui.css doesn't load in Vercel environment #308

Closed Pankwood closed 1 year ago

Pankwood commented 1 year ago

I've created an application using ExpressJS and Swagger-UI-Express. In localhost, all work fine, but when I deploy it using Vercel, the Swagger page looks funny, it looks like the CSS is not recognized. I've tried lots of things and most of the time, I don't get even an error, but one of my tries I go this:

"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."

I've created a pure application on GitHub, maybe someone can reproduce the error and explain what I am doing wrong or if it is a bug. https://github.com/Pankwood/Express-Swagger-Vercel

This is the link of the pure application deployed on Vercel. The API works fine, but Swagger doesn't. https://express-swagger-vercel.vercel.app/api-docs/

This is a question on Stackoverflow related to the issue: https://stackoverflow.com/questions/69146517/swagger-ui-vercel-unexpected-token-in-json-at-position-1/73503122#73503122

This is the index.js

const express = require('express');
const app = express();
const port = 3001;

const swaggerUi = require('swagger-ui-express');
const swaggerDocument = require('./swagger.json');

app.get('/', (req, res) => {
    res.send('Hello World!')
});

app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));

app.listen(port, () => {
    console.log(`Example app listening on port ${port}`)
});

This is the swagger.json

{
    "swagger": "2.0",
    "info": {
        "version": "1.0.0",
        "title": "Express-Swagger-Vercel",
        "description": "Express-Swagger-Vercel Test API",
        "license": {
            "name": "MIT",
            "url": "https://opensource.org/licenses/MIT"
        }
    },
    "host": "https://express-swagger-vercel.vercel.app",
    "basePath": "/",
    "schemes": [
        "http"
    ],
    "consumes": [
        "application/json"
    ],
    "produces": [
        "application/json"
    ],
    "paths": {
        "/": {
            "get": {
                "tags": [
                    "Test"
                ],
                "summary": "Get test",
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    }
}
Pankwood commented 1 year ago

I could fixed with this code::

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;
m0x61h0x64i commented 1 year ago

I could fixed with this code::

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;

what was the point?