Next.js for Amazon Alexa Skills
In this tutorial we'll build an Alexa skill that uses Next.js for the skill backend code.
Normally, when you build an Alexa skill the backend is a Lambda function.
Steps
First create a directory for the app and initialize it using npm init -y
mkdir alexa-nextjs
md alexa-nextjs
npm init -y
Replace the contents of the package.json with the following code.
package.json
{
  "private": true,
  "scripts": {
    "dev": "node server.js",
    "build": "next build",
    "start": "node server.js"
  },
  "dependencies": {
    "ask-sdk-core": "^2.11.0",
    "ask-sdk-express-adapter": "^2.11.0",
    "ask-sdk-model": "^1.37.1",
    "express": "^4.17.1",
    "next": "latest",
    "react": "^17.0.2",
    "react-dom": "^17.0.2"
  }
}
Run npm install
Create a file named server.js and add the following code.
server.js
const express = require('express')
const next = require('next')
// alexa stuff
require("ask-sdk-model")
const { ExpressAdapter } = require('ask-sdk-express-adapter')
const Alexa = require('ask-sdk-core')
const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
app.prepare().then(() => {
  const server = express()
  const skillBuilder = Alexa.SkillBuilders.custom();
  const LaunchRequestHandler = {
    canHandle(handlerInput) {
      return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
    },
    handle(handlerInput) {
      const speechText = 'Hello world';
      return handlerInput.responseBuilder
        .speak(speechText)
        .reprompt(speechText)
        .withSimpleCard('Hello World', speechText)
        .getResponse();
    }
  };
  skillBuilder.addRequestHandlers(
    LaunchRequestHandler
  )
  const skill = skillBuilder.create();
  const adapter = new ExpressAdapter(skill, false, false);
  server.post('/alexa', adapter.getRequestHandlers());
  server.all('*', (req, res) => {
    return handle(req, res)
  })
  server.listen(port, (err) => {
    if (err) throw err
    console.log(`> Ready on http://localhost:${port}`)
  })
})
Create a folder named pages and add a file named pages/index.js
mkdir pages
touch pages/index.js 
Add the following code to index.js
export default function Main() {
  return <>
    <h1>A Next.js App for Alexa</h1>
  </>
}
Make a post request
Use Postman to make the following request.
{
    "version": "1.0",
    "session": {
        "new": false,
        "sessionId": "amzn1.echo-api.session.6b87c33d-e380-4e54-a133-1430aac9e45a",
        "application": {
            "applicationId": "amzn1.ask.skill.94cb8bf9-859f-4f99-9998-b01cf13eb388"
        },
        "user": {
            "userId": "amzn1.ask.account.AFYD2ZWEIC4QLVQAPZBBRDRBAEB4URNY5IGKGHG6B2AEYLX3RENVE7W7Y6JOMZF54IG6EYGZP3HILOUKGL2ASOF75PEG6GNZPBQOHLPQL7BDSGJZRAJZOTSKUNMQDP3CGYKIZGDAPBFX6XI75KFYE6AFJAJYYAV4ANPXWXPXBXVGHWFK4JAEP4VB4EUDXSS4FPF4J5P4V3QCFKY"
        }
    },
    "context": {
        "System": {
            "application": {
                "applicationId": "amzn1.ask.skill.94cb8bf9-859f-4f99-9998-b01cf13eb388"
            },
            "user": {
                "userId": "amzn1.ask.account.AFYD2ZWEIC4QLVQAPZBBRDRBAEB4URNY5IGKGHG6B2AEYLX3RENVE7W7Y6JOMZF54IG6EYGZP3HILOUKGL2ASOF75PEG6GNZPBQOHLPQL7BDSGJZRAJZOTSKUNMQDP3CGYKIZGDAPBFX6XI75KFYE6AFJAJYYAV4ANPXWXPXBXVGHWFK4JAEP4VB4EUDXSS4FPF4J5P4V3QCFKY"
            },
            "device": {
                "deviceId": "amzn1.ask.device.AHQXHILO4X36DWVE7BKIMF4RZBRYWNVUCYMJXPCS6P2OTSU3LFXPPKJQ7RY35IVO7U53GVLALOUL7L7XBRTUNHGOOUAJUTPCLIW2QCXRQJDMWT32IJF355USGWEJTHUDAIXXUQ7VGYF7PDDPYCI4MOUJY4NQ",
                "supportedInterfaces": {}
            },
            "apiEndpoint": "https://api.amazonalexa.com",
            "apiAccessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.eyJhdWQiOiJodHRwczovL2FwaS5hbWF6b25hbGV4YS5jb20iLCJpc3MiOiJBbGV4YVNraWxsS2l0Iiwic3ViIjoiYW16bjEuYXNrLnNraWxsLjg3M2ZjM2YxLTMwYWEtNDdjMS04MjE3LTVjM2E3ODA4NjI2YyIsImV4cCI6MTU4MTgwMDgzMCwiaWF0IjoxNTgxODAwNTMwLCJuYmYiOjE1ODE4MDA1MzAsInByaXZhdGVDbGFpbXMiOnsiY29udGV4dCI6IkFBQUFBQUFBQUFDRld2Zyt6cWEzR1dBWGVsTTZScjdqSXdFQUFBQUFBQUJrVUFWeVU2cTU0QjhOQmRTR2FRRm9EMjZ6M0hEN3hNb0s3SVNuTG8xNGxPcXovY1dENFIvbUl3ZWFTa2t0YnVJaHlZdFRzdDc3TkRvaituSm5QVFpVRWdqNGI2Wmd2cGpUM3N6UGlZRzBkRW12R0NuSDRBV2tQWXNjOXAzbkxubEthN09BV01HRXVseC9KWmQyT25Zbk42LzlnbzloZUZzVlppNjFvQytxa3RvTGpPd0NtS2NCcmFnc3F3TGpuendmdDJEZkpsdzZnVjY5dTNFc3RBU3VpQ2ZpaXJqRWw0YnBSdXU0cmFyMDFESHgwUGxtR3MwU3NmSXhPdmVkUk00bmRQNGxENGJnTm9BcXVySWFJWDNNSjA4VDVkRlNWTlEvcGhzNDVaemdSVWUvMkNrUmNyZHgvTG9tWnZYZytTdm9id1hwZmQ3NVpoVlM0R0o2K3RkRE9Zcjg4UFl6aVlLOEx4SFJjR3Fha0dTUlliak5QSTgrYlRQLzg5bWhKVTd4aGI0PSIsImNvbnNlbnRUb2tlbiI6bnVsbCwiZGV2aWNlSWQiOiJhbXpuMS5hc2suZGV2aWNlLkFHUFc1SFc0S0oyQk5SVU5FUldKSFlBNUVNTktaU0UyS0FEVjdNQ1JQQkpTVFhRNFBFU1pYWUlPU0FWSlNXWTNGVkJHWFA2RlRSQ0ZGTlRYSlRYV09GMlU2WEdONEZMRU9XWklWWjQ1WVVKSjNGRU40R1BTNVpGUFNKT0dHV1JVN0MyNTZXRjdZQUU2VVJPQjRGTFBVVTJSV1pTQSIsInVzZXJJZCI6ImFtem4xLmFzay5hY2NvdW50LkFIR0lOS0tDWVZIRkxJWUpESVY1VlBBUFJRRVJCSVRBTlpPUlNCVVc0U09FRzVHQklNV1BKRVlRUlNCVVdSWVNYWTVIRTJTUDYzTjdVWFlRTE5SM0tTS1JMTkZOSFNQUkhIRjVJNVg2NzdGRlZSS01XT0RBQlNZVjNYQUhUSlc1RTNOQzdDQVBISVdUNjVXNkozREY0NUtCNDdaWllXSkJVR0pRUzVUTkNNUVlZSUsyTUJaVEFXWEE0RDJTVDVHQUY2S0JHVk5IVE9KQ1gzUSJ9fQ.O4UOt68MrARJc5vqMZixLzOXGlmo4L4IXAKwQUgAKTtcTL5F7XnrYAbyEkh6UbWu8Izffdf5mUmAh-q_m3Oa7YuD5yyoq_nWUc2giKGLLQ5J5yNnITCN3nOXi6AgU0Cb-ix_EFq24fsklb4Rlp-W0y36UkXI7TZxObF9BGHUJW284Q-H4v6n_tCtMtno1-uAImbLuwoaJb1fij6V8XH_iB_GIN6rvsD-HIkflsqVirdByjYYsuaR8xQ2xlnxII5eBb2iRDi1cVwuXzMsBLWFZHqCyXDtvOwZcl4OJt4E1nQ9hU175Hqu-wf7iiSptV_oIwtUY01x5xpQK0b_RvrwSg"
        },
        "Viewport": {
            "experiences": [
                {
                    "arcMinuteWidth": 246,
                    "arcMinuteHeight": 144,
                    "canRotate": false,
                    "canResize": false
                }
            ],
            "shape": "RECTANGLE",
            "pixelWidth": 1024,
            "pixelHeight": 600,
            "dpi": 160,
            "currentPixelWidth": 1024,
            "currentPixelHeight": 600,
            "touch": [
                "SINGLE"
            ],
            "video": {
                "codecs": [
                    "H_264_42",
                    "H_264_41"
                ]
            }
        },
        "Viewports": [
            {
                "type": "APL",
                "id": "main",
                "shape": "RECTANGLE",
                "dpi": 160,
                "presentationType": "STANDARD",
                "canRotate": false,
                "configuration": {
                    "current": {
                        "video": {
                            "codecs": [
                                "H_264_42",
                                "H_264_41"
                            ]
                        },
                        "size": {
                            "type": "DISCRETE",
                            "pixelWidth": 1024,
                            "pixelHeight": 600
                        }
                    }
                }
            }
        ]
    },
    "request": {
        "type": "LaunchRequest",
        "requestId": "amzn1.echo-api.request.a6d058dd-945e-4a9f-bd9a-a9f2c0e6221f",
        "timestamp": "2020-02-15T21:02:10Z",
        "locale": "en-US",
        "reason": "USER_INITIATED"
    }
}