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

Understanding how to parse an array of arrays in JavaScript can be a

Looking for a function that can extract a value from an array containing multiple arrays? Simply use getValueFromArray(array, [2, 4]) to get the 4th element of the 2d array within the main array. Check out the code snippet below: function getValueFromArr ...

Exploring ways to access data stored in interconnected models, such as MongoDB and NodeJS

As a newcomer to querying, I attempted a unique exercise to practice but unfortunately did not achieve the desired outcome. I have three models: const userSchema = new Schema({ info1: String, info2: String }, const serviceSchema = new Schema( { name ...

Transform an array of strings into an array of floating point numbers using AngularJS

Hey everyone! I'm having trouble converting an array of strings into floats. When using map(parseFloat), I'm only getting integer numbers. Could the issue be with the commas in 40,78 causing parseFloat to interpret it as 40 instead of 40.78? Her ...

Using AngularJS to transfer data from a datepicker to an ng-model

I am currently trying to figure out how to pass the date from a datetimepicker into the model. Unfortunately, I am facing some challenges with this process. I wish I could provide a demo of the issue on a fiddle, but I am unsure of how to do so due to the ...

Unexpected issue: Ajax success function not displaying anything in the console

My code seems to be running without any output in the console. I am attempting to verify the data in order to trigger specific actions based on whether it is correct or not. However, the if-else conditions are not functioning as expected. Below is a snip ...

I am attempting to retrieve the initial three results from my MySQL database using Node.js, but I keep encountering an error

Below is the code I am currently using: con.query('SELECT * FROM tables', function(err, results) { if (err) throw err console.log(results[0].rawname) for(var i= 0; i <= 3; i++) { ...

How to programmatically unselect an ng-checkbox in AngularJS when it is removed from an array

Utilizing checkboxes to gather values and store them in an array for dataset filtering purposes. The objectives are as follows: Show child filters when parent category is selected. Unselect all children if parent is unselected (otherwise they will ...

`Save user edits on the webpage using Electron`

I am encountering an issue with my electron app. I use the window.loadUrl() method to navigate between pages. Some of these pages require users to input data that needs to be saved. The problem arises when a user enters information, moves to another page ...

Ways to verify if a Discord.js snowflake is present in a collection of other identification numbers

I'm currently developing a Discord.js bot and I want to create a system where only specific IDs listed in a JSON file can trigger certain commands. However, I'm unsure about how to implement this logic within an if statement. if (message.author. ...

Can you choose and generate identical values using react-select?

I am working on implementing a multi Creatable feature where users can select a preset value or create a new value during the same interaction. To illustrate, here is my current render: import CreatableSelect from 'react-select/creatable'; functi ...

eliminating parameters in URL for redirection in Next.js

I'm encountering an issue with the code snippet provided. When I try to redirect to /home and pass an email variable, the address bar displays http://localhost:4000/[email protected]. Can anyone suggest a clean way to pass variables using react a ...

Tips for modifying JSON property names during the parsing process

As outlined in the JSON.parse documentation, a reviver function can be utilized to modify the value of each property within the JSON data. Here is an example: JSON.parse('{"FirstNum": 1, "SecondNum": 2, "ThirdNum": 3}', function(k, v) { return ...

Is there a method to prevent data loss on page refresh by persisting data stored in a database?

I'm currently developing a commenting feature for a blog using the latest version of NextJs. The text input collects data and sends it to the 'Vercel' hosted database. I am able to successfully fetch the data from the frontend as expected. ...

Identify the mouse's location in relation to its parent element, not the entire webpage

A script I've been working on detects the mouse position relative to the page, taking into account a movement threshold of 100px before triggering certain actions. // Keep track of last cursor positions var cursorDistance = 0; var lastCursorX = null; ...

Numerals for Central Leaflet Marker

Is there a way to effectively center numbers inside markers? Here is the current situation: View Marker with Number How to Create a Marker return L.divIcon({ className: "green-icon", iconSize: [25, 41], iconAnchor: [10, 44], popupAn ...

JavaScript Object Featuring a Default Function Along with Additional Functions

I'm currently working on developing a custom plugin, but I've hit a roadblock at the initial stage. My goal is to create an object that can accept a parameter as its default and also include other functions within it. Below is an example of what ...

Addressing the issue of prolonged Electron initialization

Scenario After spending considerable time experimenting with Electron, I have noticed a consistent delay of over 2.5 seconds when rendering a simple html file on the screen. The timeline of events unfolds like this: 60 ms: app ready event is triggered; a ...

Using the DatePicker component with non-escaped Latin alphabet characters in date-fns for ReactJS

While attempting to integrate the DatePicker component from Material UI into my React project, I encountered an error. Although many attributed the issue to a version discrepancy, what ultimately resolved the problem for me was assigning a value to the Da ...

Could Ramda assist in enhancing pipeline/composition processes with a logging feature?

Considering implementing logging within a composed chain of functions, the following code demonstrates how it can be achieved: const f = R.compose( transformation2, doAlso(x => console.log(`id: ${x.id}`)), transformation1 ) This approach would c ...

Insert a div element into the JavaScript file

I have a JavaScript code snippet that needs to be inserted after the "Artwork" section. Here is the code: <div class="image-upload"> <label for="files"> <img src="ohtupload.jpg"> </label> </di ...