Using Swagger with Next.js

Is it possible to generate Swagger documentation for API routes in NEXT.js? I am working with Next.js for both front-end and back-end tasks, and I am interested in creating a Swagger documentation for the APIs implemented in Next.js.

Answer №1

If you're looking to streamline the integration between Next.js and Swagger, check out this project:

yarn add next-swagger-doc swagger-ui-react
import { GetStaticProps, InferGetStaticPropsType } from 'next';

import { createSwaggerSpec } from 'next-swagger-doc';
import SwaggerUI from 'swagger-ui-react';
import 'swagger-ui-react/swagger-ui.css';

const ApiDoc = ({ spec }: InferGetStaticPropsType<typeof getStaticProps>) => {
  return <SwaggerUI spec={spec} />;
};

export const getStaticProps: GetStaticProps = async ctx => {
  const spec: Record<string, any> = createSwaggerSpec({
    title: 'NextJS Swagger',
    version: '0.1.0',
  });
  return { props: { spec } };
};

export default ApiDoc;

This is how a Next.js API route endpoint is defined:

/**
 * @swagger
 * /api/hello:
 *   get:
 *     description: Returns the hello world
 *     responses:
 *       200:
 *         description: hello world
 */
const handler = (_req: NextApiRequest, res: NextApiResponse) => {
  res.status(200).json({
    result: 'hello world',
  });
};

Answer №2

I created a handy npm library that automatically generates Swagger documentation from your NextJS project without requiring any user input!

Although it's still in the early Beta stage, I hope you find it helpful. https://www.npmjs.com/package/nextjs-routes-docs

To use, simply execute

npx nextjs-routes-docs [dir]

Answer №3

It's essential to have the swagger json files or specification for the APIs and utilize libraries like Swagger UI or Redoc

By using Redoc, you can implement a /doc/[slug].js to dynamically fetch the .json or yaml files for your documentation (or swagger ui)

This page: , offers an array of tools for React and OpenAPI in general that are worth exploring.

Answer №4

To implement this feature, follow these steps after annotating your route.js files with JSDoc ie. @swagger in NextJS 13.

Step 1.

Start by installing the necessary dependencies:

npm i swagger-ui-react swagger-jsdocs

Step 2.

Next, create a component file named src/components/swagger-doc.jsx to display the Swagger documentation using swagger-ui-react

'use client';

// Import Modules
import PropTypes from 'prop-types';

// Import Components
import SwaggerUI from 'swagger-ui-react';

// Import Miscs
import 'swagger-ui-react/swagger-ui.css';

const SwaggerDoc = ({ spec }) => (
  <SwaggerUI spec={spec} />
);

SwaggerDoc.propTypes = {
  /**
   * OpenApi specifications
   */
  spec: PropTypes.oneOfType([PropTypes.object]).isRequired,
};

export default SwaggerDoc;

Step 3.

Create a configuration file called src/configs.js where you define options for swagger-jsdocs

const CONFIG = {
  jsDocs: {
    apis: ['**/api/v1/**/route.js'],
    swaggerDefinition: {
      info: {
        title: 'Some Service',
        version: '0.0.1',
        description: 'This is an API doc for Some Service.',
      },
    },
  },
};

export default CONFIG;

Step 4.

Now, set up a /docs route by creating src/app/docs/page.jsx

// Import Modules
import swaggerJsdoc from 'swagger-jsdoc';

// Import Components
import SwaggerDoc from '../../components/swagger-doc';

// Import Miscs
import CONFIG from '../../configs';

const getData = async () => {
  const spec = swaggerJsdoc(CONFIG.jsDocs);

  return spec;
};

const Docs = async () => {
  const data = await getData();

  return <SwaggerDoc spec={data} />;
};

export default Docs;

Note: For detailed configurations of the dependencies, refer to the following links:

swagger-jsdoc swagger-ui-react

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Are Viewmodel contents empty after ajax request?

Currently working on an ASP.NET MVC application, I am in the process of developing a search page that showcases both the search box and the table of results simultaneously. To achieve this functionality, I have utilized Partial Views along with AJAX/JSON c ...

Renaming form elements using JQuery's .load method

This is a page named A.html <form name=form> <input type=text id = txtA> </form> When I use jQuery to load it into B.html, it loads multiple times. <form name=form> <input type=text id = txtA> </form> <form name=f ...

AngularJS is not responding to a 400 bad request

Despite my efforts to find solutions on Google and Stack Overflow for similar or identical issues, as a newcomer, none of them have provided me with any insight on how to resolve the issues in my code. Here is the script I am working with: $http.post(&ap ...

Display/Conceal JavaScript

I recently implemented a JavaScript function on my website to show/hide specific elements. However, being new to JavaScript, I have encountered some difficulties. I've spent quite some time troubleshooting the code but haven't been able to pinpoi ...

Adding color between lines in Three.js

I have two different sets of vertices. One set contains real vertices, and the other set contains the same vertices but with a y value of zero. I am trying to connect these vertices and fill them in but have not been successful so far. I have attempted to ...

A tutorial on how to create the appearance of disabled buttons that look the same as enabled buttons through the use

My button includes a text field that is constantly disabled. I would like for the text field to appear as bright as it does when the button is enabled. After disabling the button, they both appear dimmer compared to others and the text field follows suit ...

Having trouble with NVM not working correctly in Ubuntu 21.04 Terminal?

Lately, I've been facing challenges with updating my Node.js version, and one method I tried was using node version manager. After downloading the install_nvm.sh file with the command curl -sL https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/insta ...

What causes the sudden change in value of this array?

I can't seem to figure out what's going on with this question. It might be something silly, but I haven't been able to find any clues. Here is the array in question: const superVillains = [ { value: '1', label: 'Thanos&apo ...

Customize React JS Material UI's InputBase to be responsive

https://i.stack.imgur.com/9iHM1.gif Link: codesandbox Upon reaching a certain threshold, like on mobile devices, the elements inside should stack vertically instead of horizontally, taking up full length individually. How can this be achieved? ...

Leveraging GSAP and Vue by utilizing props to dynamically calculate a maxWidth

I am working on animating buttons in my application using GSAP. The idea is that when a user clicks the button, it should animate the maxWidth of the button. I want this to be dynamic by adding a percentage of the max width set using props. Is it possibl ...

Difficulty encountered while connecting JSON data to a list using Angular JS

Currently, I am working on developing an application using AngularJS. In this project, I need to populate the customer list using data from a database. To achieve this, I have written a web method to retrieve the necessary data: [WebMethod] [ScriptMet ...

Looking to align the labels of material UI tabs to the left instead of their default center alignment? Here's how

Is there a way to align material ui tab labels to the left instead of center by default? View an image demonstrating center aligned tab labels here ...

What is the best way to specify a submission destination for a custom form component in Vue?

I am looking to streamline the use of a form component across my website, however, I need the submit button to perform different actions depending on which page calls the form-component. Experimenting with Vue components and data passing is new to me as I ...

Error message: ReactJs is throwing a TypeError due to mod not being recognized as a function

After updating Swiper from version 9.3.2 to 10.2.0, a new issue has arisen in my reactJs project that says TypeError: mod is not a function. ...

React and SASS - issue with checkbox component not being properly aligned with its label

I'm brand new to React and I'm currently in the process of converting a pure HTML page into a React component. How can I adjust the SASS stylesheet to match the original HTML layout? Here is my current React setup (the checkbox displays on the r ...

Issue with handling keypress event and click event in Internet Explorer

Below is the HTML code for an input text box and a button: <div id="sender" onKeyUp="keypressed(event);"> Your message: <input type="text" name="msg" size="70" id="msg" /> <button onClick="doWork();">Send</button> </di ...

NodeJS video streaming feature does not close the connection when the user disconnects or navigates to a different page

Currently, I'm in the process of developing a video streaming server using nodeJS with express. To monitor the progress status, I am utilizing the "request-progress" module. So far, everything pertaining to video streaming is working perfectly. Howev ...

Tips for Choosing the Right Objects in Vue.js

I have the following code that combines all objects in a person and stores them in an array called Cash:[] this.cash = person.userinvoice.concat(person.usercashfloat) Inside person.usercashfloat, there is an element called validate which sometimes equals ...

How does the pound sign (#) signal the beginning of a comment in JavaScript?

I recently ran into an issue while trying to minify JavaScript using Grunt in my NPM project. The error thrown by Uglify was: Warning: Uglification failed. Unexpected character '#'. Line 1 in app/min-libs/node_modules/grunt-contrib-jshint/node_m ...

Issue with checkboxes preventing submission of form

Currently working on a website project for a company that requires certain steps to be completed for deliveries. Unfortunately, I am facing issues with the submit button, and I apologize as I am still new to this. The code I have pasted is divided into tw ...