Zero config PWA plugin for Next.js, with workbox 🧰

Overview

Zero Config PWA Plugin for Next.js

This plugin is powered by workbox and other good stuff.

size dependencies downloads license

Features

  • 0️⃣ Zero config for registering and generating a service worker
  • Optimized precache and runtime cache
  • 💯 Maximize lighthouse score
  • 🎈 Easy to understand examples
  • 📴 Completely offline support
  • 📦 Use workbox and workbox-window v6
  • 🍪 Work with cookies out of the box
  • No custom server needed for Next.js 9+ example
  • 🔧 Handle PWA lifecycle events opt-in example
  • 📐 Custom worker to run extra code in service worker with code splitting example
  • 🐞 Debug service worker with confidence in development mode without caching
  • 🌏 Internationalization (a.k.a I18N) with next-i18next example
  • 🛠 Configurable by the same workbox configuration options for GenerateSW and InjectManifest
  • 🚀 Spin up a GitPod and try out examples in rocket speed
  • 🔩 (Experimental) precaching .module.js when next.config.js has experimental.modern set to true

NOTE - next-pwa version 2.0.0+ should only work with next.js 9.1+, and static files should only be served through public directory. This will make things simpler.


Open in Gitpod

Install

If you are new to next.js or react.js at all, you may want to first checkout learn next.js or next.js document. Then start from a simple example or progressive-web-app example in next.js repository.

yarn add next-pwa

Basic Usage

Step 1: withPWA

Update or create next.config.js with

const withPWA = require('next-pwa')

module.exports = withPWA({
  // other next config
})

After running next build, this will generate two files in your distDir (default is .next folder): workbox-*.js and sw.js, which you need to serve statically, either through static file hosting service or using custom server.js.

If you are using Next.js 9+, you may not need a custom server to host your service worker files. Skip to next section to see the details.

Option 1: Host Static Files

Copy files to your static file hosting server, so that they are accessible from the following paths: https://yourdomain.com/sw.js and https://yourdomain.com/workbox-*.js.

One example is using Firebase hosting service to host those files statically. You can automate the copy step using scripts in your deployment workflow.

For security reasons, you must host these files directly from your domain. If the content is delivered using a redirect, the browser will refuse to run the service worker.

Option 2: Use Custom Server

When an HTTP request is received, test if those files are requested, then return those static files.

Example server.js

const { createServer } = require('http')
const { join } = require('path')
const { parse } = require('url')
const next = require('next')

const app = next({ dev: process.env.NODE_ENV !== 'production' })
const handle = app.getRequestHandler()

app.prepare()
  .then(() => {
    createServer((req, res) => {
      const parsedUrl = parse(req.url, true)
      const { pathname } = parsedUrl
      
      if (pathname === '/sw.js' || pathname.startsWith('/workbox-')) {
        const filePath = join(__dirname, '.next', pathname)
        app.serveStatic(req, res, filePath)
      } else {
        handle(req, res, parsedUrl)
      }
    })
    .listen(3000, () => {
      console.log(`> Ready on http://localhost:${3000}`)
    })
  })

The following setup has nothing to do with next-pwa plugin, and you probably have already set them up. If not, go ahead and set them up.

Step 2: Add Manifest File (Example)

Create a manifest.json file in your static folder:

{
  "name": "PWA App",
  "short_name": "App",
  "icons": [
    {
      "src": "/static/icons/android-chrome-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "/static/icons/android-chrome-384x384.png",
      "sizes": "384x384",
      "type": "image/png"
    },
    {
      "src": "/static/icons/icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ],
  "theme_color": "#FFFFFF",
  "background_color": "#FFFFFF",
  "start_url": "/",
  "display": "standalone",
  "orientation": "portrait"
}

Step 3: Add Head Meta (Example)

Add the following into _document.jsx or _document.tsx, in <Head>:

<meta name='application-name' content='PWA App' />
<meta name='apple-mobile-web-app-capable' content='yes' />
<meta name='apple-mobile-web-app-status-bar-style' content='default' />
<meta name='apple-mobile-web-app-title' content='PWA App' />
<meta name='description' content='Best PWA App in the world' />
<meta name='format-detection' content='telephone=no' />
<meta name='mobile-web-app-capable' content='yes' />
<meta name='msapplication-config' content='/static/icons/browserconfig.xml' />
<meta name='msapplication-TileColor' content='#2B5797' />
<meta name='msapplication-tap-highlight' content='no' />
<meta name='theme-color' content='#000000' />
          
<link rel='apple-touch-icon' sizes='180x180' href='/static/icons/apple-touch-icon.png' />
<link rel='icon' type='image/png' sizes='32x32' href='/static/icons/favicon-32x32.png' />
<link rel='icon' type='image/png' sizes='16x16' href='/static/icons/favicon-16x16.png' />
<link rel='manifest' href='/static/manifest.json' />
<link rel='mask-icon' href='/static/icons/safari-pinned-tab.svg' color='#5bbad5' />
<link rel='shortcut icon' href='/static/icons/favicon.ico' />
<link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Roboto:300,400,500' />
     
<meta name='twitter:card' content='summary' />
<meta name='twitter:url' content='https://yourdomain.com' />
<meta name='twitter:title' content='PWA App' />
<meta name='twitter:description' content='Best PWA App in the world' />
<meta name='twitter:image' content='https://yourdomain.com/static/icons/android-chrome-192x192.png' />
<meta name='twitter:creator' content='@DavidWShadow' />
<meta property='og:type' content='website' />
<meta property='og:title' content='PWA App' />
<meta property='og:description' content='Best PWA App in the world' />
<meta property='og:site_name' content='PWA App' />
<meta property='og:url' content='https://yourdomain.com' />
<meta property='og:image' content='https://yourdomain.com/static/icons/apple-touch-icon.png' />

Tip: Put the viewport head meta tag into _app.js rather than in _document.js if you need it.

<meta name='viewport' content='minimum-scale=1, initial-scale=1, width=device-width, shrink-to-fit=no, user-scalable=no, viewport-fit=cover' />

Usage Without Custom Server (next.js 9+)

Thanks to Next.js 9+, we can use the public folder to serve static files from the root / URL path. It cuts the need to write custom server only to serve those files. Therefore the setup is easier and concise. We can use next.config.js to config next-pwa to generates service worker and workbox files into the public folder.

withPWA

const withPWA = require('next-pwa')

module.exports = withPWA({
  pwa: {
    dest: 'public'
  }
})

Use this example to see it in action

Configuration

There are options you can use to customize the behavior of this plugin by adding pwa object in the next config in next.config.js:

const withPWA = require('next-pwa')

module.exports = withPWA({
  pwa: {
    disable: process.env.NODE_ENV === 'development',
    register: true,
    scope: '/app',
    sw: 'service-worker.js',
    //...
  }
})

Available Options

  • disable: boolean - whether to disable pwa feature as a whole
    • default to false
    • set disable: false, so that it will generate service worker in both dev and prod
    • set disable: true to completely disable PWA
    • if you don't need to debug service worker in dev, you can set disable: process.env.NODE_ENV === 'development'
  • register: boolean - whether to let this plugin register service worker for you
    • default to true
    • set to false when you want to handle register service worker yourself, this could be done in componentDidMount of your root app. you can consider the register.js as an example.
  • scope: string - url scope for pwa
    • default to /
    • set to /app so that path under /app will be PWA while others are not
  • sw: string - service worker script file name
    • default to /sw.js
    • set to another file name if you want to customize the output file name
  • runtimeCaching - caching strategies (array or callback function)
    • default: see the Runtime Caching section for the default configuration
    • accepts an array of cache entry objects, please follow the structure here
    • Note: the order of the array matters. The first rule that matches is effective. Therefore, please ALWAYS put rules with larger scope behind the rules with a smaller and specific scope.
  • publicExcludes - an array of glob pattern strings to exclude files in the public folder from being precached.
    • default: [] - this means that the default behavior will precache all the files inside your public folder
    • example: ['!img/super-large-image.jpg', '!fonts/not-used-fonts.otf']
  • buildExcludes - an array of extra pattern or function to exclude files from being precached in .next/static (or your custom build) folder
    • default: []
    • example: [/chunks\/images\/.*$/] - Don't precache files under .next/static/chunks/images (Highly recommend this to work with next-optimized-images plugin)
    • doc: Array of (string, RegExp, or function()). One or more specifiers used to exclude assets from the precache manifest. This is interpreted following the same rules as Webpack's standard exclude option.
  • subdomainPrefix: string - url prefix to allow hosting static files on a subdomain
    • default: "" - i.e. default with no prefix
    • example: /subdomain if the app is hosted on example.com/subdomain

Other Options

next-pwa uses workbox-webpack-plugin, other options which could also be put in pwa object can be found ON THE DOCUMENTATION for GenerateSW and InjectManifest. If you specify swSrc, InjectManifest plugin will be used, otherwise GenerateSW will be used to generate service worker.

Runtime Caching

next-pwa uses a default runtime cache.js

There is a great chance you may want to customize your own runtime caching rules. Please feel free to copy the default cache.js file and customize the rules as you like. Don't forget to inject the configurations into your pwa config in next.config.js.

Here is the document on how to write runtime caching configurations, including background sync and broadcast update features and more!

Tips

  1. Common UX pattern to ask user to reload when new service worker is installed
  2. Use a convention like {command: 'doSomething', message: ''} object when postMessage to service worker. So that on the listener, it could do multiple different tasks using if...else....
  3. When you are debugging service worker, constantly clean application cache to reduce some flaky errors.
  4. If you are redirecting the user to another route, please note workbox by default only cache response with 200 HTTP status, if you really want to cache redirected page for the route, you can specify it in runtimeCaching such as options.cacheableResponse.statuses=[200,302].
  5. When debugging issues, you may want to format your generated sw.js file to figure out what's really going on.
  6. Force next-pwa to generate worker box production build by specify the option mode: 'production' in your pwa section of next.config.js. Though next-pwa automatically generate the worker box development build during development (by running next) and worker box production build during production (by running next build and next start). You may still want to force it to production build even during development of your web app for following reason:
    1. Reduce logging noise due to production build doesn't include logging.
    2. Improve performance a bit due to production build is optimized and minified.
  7. If you just want to disable worker box logging while keeping development build during development, simply put self.__WB_DISABLE_DEV_LOGS = true in your worker/index.js (create one if you don't have one).

Reference

  1. Google Workbox
  2. ServiceWorker, MessageChannel, & postMessage by Nicolás Bevacqua
  3. The Service Worker Lifecycle

License

MIT

Issues
  • Next 10.0.6 , Build Error: Cannot find module 'webpack'

    Next 10.0.6 , Build Error: Cannot find module 'webpack'

    Summary

    Next 10.0.6 , Build Error: Cannot find module 'webpack'

    • C:\sources\a\node_modules\workbox-webpack-plugin\build\generate-sw.js
    • C:\sources\a\node_modules\workbox-webpack-plugin\build\index.js
    • C:\sources\a\node_modules\next-pwa\index.js
    • C:\sources\a\next.config.js
    • C:\sources\a\node_modules\next\dist\next-server\server\config.js
    • C:\sources\a\node_modules\next\dist\build\index.js
    • C:\sources\a\node_modules\next\dist\cli\next-build.js
    • C:\sources\a\node_modules\next\dist\bin\next

    How To Reproduce

    yarn build with.:

    • next: 10.0.6, 10.0.7
    • next-pwa ^5.0.3
    bug 
    opened by meotimdihia 31
  • no matching service worker detected. you may need to reload the page or check that the scope of the service worker for the current page encloses the scope and start url from the manifest

    no matching service worker detected. you may need to reload the page or check that the scope of the service worker for the current page encloses the scope and start url from the manifest

    Hello, I've been trying to setup next-pwa for the past two days but with no luck at all. Here's my next config:

    require('dotenv').config();
    const path = require('path');
    const Dotenv = require('dotenv-webpack');
    const withPWA = require('next-pwa');
    const withPlugins = require('next-compose-plugins');
    
    const nextConfig = {
        webpack: (config, { isServer }) => {
            // Fixes npm packages that depend on `fs` module
            if (!isServer) {
                config.node = {
                    fs: 'empty',
                };
            }
            // Read the .env file
            config.plugins = [
                ...config.plugins,
                new Dotenv({
                    path: path.join(__dirname, process.env.ENV_FILE_PATH || '.env'),
                    systemvars: true,
                }),
            ];
            return config;
        },
    };
    
    module.exports = withPlugins(
        [
            [
                withPWA,
                {
                    pwa: {
                        dest: 'public',
                        sw: 'service-worker.js',
                        maximumFileSizeToCacheInBytes: 3000000,
                    },
                },
            ],
        ],
        nextConfig
    );
    

    Next.js v9.2.1

    server.js even though it's not required since v9 as mentioned in the docs, but I tried anyways

                    if (
                        pathname === '/service-worker.js' ||
                        pathname.startsWith('/workbox-')
                    ) {
                        const filePath = join(__dirname, '.next', pathname);
                        app.serveStatic(req, res, filePath);
                    }
    

    /public/manifest.json

    {
      "name": "hello",
      "short_name": "hello",
      "theme_color": "#00a699",
      "background_color": "#ffffff",
      "display": "standalone",
      "orientation": "portrait",
      "scope": "/",
      "start_url": "/",
      "icons": [
        {
          "src": "images/icons/icon-72x72.png",
          "sizes": "72x72",
          "type": "image/png"
        },
        {
          "src": "images/icons/icon-96x96.png",
          "sizes": "96x96",
          "type": "image/png"
        },
        {
          "src": "images/icons/icon-128x128.png",
          "sizes": "128x128",
          "type": "image/png"
        },
        {
          "src": "images/icons/icon-144x144.png",
          "sizes": "144x144",
          "type": "image/png"
        },
        {
          "src": "images/icons/icon-152x152.png",
          "sizes": "152x152",
          "type": "image/png"
        },
        {
          "src": "images/icons/icon-192x192.png",
          "sizes": "192x192",
          "type": "image/png"
        },
        {
          "src": "images/icons/icon-384x384.png",
          "sizes": "384x384",
          "type": "image/png"
        },
        {
          "src": "images/icons/icon-512x512.png",
          "sizes": "512x512",
          "type": "image/png"
        }
      ],
      "splash_pages": null
    }
    

    Any help is highly appreciated.

    done 
    opened by omar-dulaimi 30
  • Uncaught (in promise) TypeError: Failed to fetch Nextjs PWA using next-pwa in Chrome

    Uncaught (in promise) TypeError: Failed to fetch Nextjs PWA using next-pwa in Chrome

    Hi I was working on a Nextjs proyect and i try to convert it to a PWA using next-pwa, first i created the next.config.js

    Screenshot from 2021-03-09 19-15-26

    then created the manifest.json

    { "name": "PRONTO APP", "short_name": "PRONTO", "icons": [ { "src": "/icon.png", "sizes": "128x128", "type": "image/png" }, { "src": "/icon-512x512.png", "sizes": "512x512", "type": "image/png" } ], "theme_color": "#FFFFFF", "background_color": "#FFFFFF", "start_url": "/", "display": "standalone", "orientation": "portrait" }

    And I add the meta data in de _document file in pages

    Screenshot from 2021-03-09 19-10-02

    But when i run:

    npm build dev npm start

    in Google Chrome My PWA works fine but in console i get this error, in other browsers this error doesn't appear:

    Screenshot from 2021-03-09 19-11-44

    And I really dont know why, running the app in dev mod with npm run dev i get the following messages in chrome:

    Screenshot from 2021-03-09 19-03-35

    This is my public folder structure:

    Screenshot from 2021-03-09 19-19-07

    I was trying to do the same thing in this video. https://www.youtube.com/watch?v=8enp-acPbRE

    Can Anyone Help me plss

    bug done 
    opened by jpbmdev 24
  • Error on build

    Error on build "TypeError: Cannot read property 'tapPromise' of undefined"

    I get that error when building since using Webpack 5 and Next.js 10:

    > yarn build
    yarn run v1.22.10
    $ NODE_ENV=production next build
    Loaded env from /Users/flayks/sites/atelier-m/.env.local
    (node:18901) [DEP_WEBPACK_SINGLE_ENTRY_PLUGIN] DeprecationWarning: SingleEntryPlugin was renamed to EntryPlugin
    (Use `node --trace-deprecation ...` to show where the warning was created)
    > [PWA] Compile client (static)
    > [PWA] Auto register service worker with: /Users/flayks/sites/atelier-m/node_modules/next-pwa/register.js
    > [PWA] Service worker: /Users/flayks/sites/atelier-m/public/sw.js
    > [PWA]   url: /sw.js
    > [PWA]   scope: /
    > [PWA] Compile server
    
    > Build error occurred
    TypeError: Cannot read property 'tapPromise' of undefined
        at /Users/flayks/sites/atelier-m/node_modules/next-pwa/node_modules/workbox-webpack-plugin/build/generate-sw.js:242:41
        at SyncHook.eval [as call] (eval at create (/Users/flayks/sites/atelier-m/node_modules/tapable/lib/HookCodeFactory.js:19:10), <anonymous>:9:1)
        at SyncHook.lazyCompileHook (/Users/flayks/sites/atelier-m/node_modules/tapable/lib/Hook.js:154:20)
        at Compiler.newCompilation (/Users/flayks/sites/atelier-m/node_modules/next/node_modules/webpack/lib/Compiler.js:630:30)
        at /Users/flayks/sites/atelier-m/node_modules/next/node_modules/webpack/lib/Compiler.js:667:29
        at AsyncSeriesHook.eval [as callAsync] (eval at create (/Users/flayks/sites/atelier-m/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:6:1)
        at AsyncSeriesHook.lazyCompileHook (/Users/flayks/sites/atelier-m/node_modules/tapable/lib/Hook.js:154:20)
        at Compiler.compile (/Users/flayks/sites/atelier-m/node_modules/next/node_modules/webpack/lib/Compiler.js:662:28)
        at /Users/flayks/sites/atelier-m/node_modules/next/node_modules/webpack/lib/Compiler.js:321:11
        at Compiler.readRecords (/Users/flayks/sites/atelier-m/node_modules/next/node_modules/webpack/lib/Compiler.js:529:11)
        at /Users/flayks/sites/atelier-m/node_modules/next/node_modules/webpack/lib/Compiler.js:318:10
        at AsyncSeriesHook.eval [as callAsync] (eval at create (/Users/flayks/sites/atelier-m/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:6:1)
        at AsyncSeriesHook.lazyCompileHook (/Users/flayks/sites/atelier-m/node_modules/tapable/lib/Hook.js:154:20)
        at /Users/flayks/sites/atelier-m/node_modules/next/node_modules/webpack/lib/Compiler.js:315:19
        at AsyncSeriesHook.eval [as callAsync] (eval at create (/Users/flayks/sites/atelier-m/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:15:1)
        at AsyncSeriesHook.lazyCompileHook (/Users/flayks/sites/atelier-m/node_modules/tapable/lib/Hook.js:154:20)
    error Command failed with exit code 1.
    

    It builds fine when not using next-pwa

    module.exports = config
    

    or using next-offline

    module.exports = withOffline(config)
    

    The config:

    const config = {
        // Env
        env: {
            localesMap: {
                fr: 'fr-fr',
                en: 'en-us'
            }
        },
    
        // Internationalization
        i18n: {
            locales: ['en', 'fr'],
            defaultLocale: 'en'
        },
    
        // PWA options
        pwa: {
            disable: process.env.NODE_ENV === 'development',
            dest: 'public'
        },
    
        // Headers
        async headers() {
            return [{
                source: '/(.*)',
                headers: [
                    { key: 'X-Frame-Options', value: 'SAMEORIGIN', },
                    { key: 'X-Content-Type-Options', value: 'nosniff' },
                    { key: 'X-XSS-Protection', value: '1; mode=block' },
                    { key: 'Strict-Transport-Security', value: 'max-age=31536000; includeSubDomains; preload' },
                ],
            }]
        },
    }
    
    bug 
    opened by flayks 17
  • Unable to build project that includes a custom worker file

    Unable to build project that includes a custom worker file

    Summary

    Whenever I try to build a next-pwa project that includes a custom worker js file, the build fails with the following error:

    info  - Creating an optimized production build ..buffer.js:333
      throw new ERR_INVALID_ARG_TYPE(
      ^
    
    TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received undefined
        at Function.from (buffer.js:333:9)
        at writeOut (C:\Users\sdqui\Desktop\next-pwa\examples\custom-worker\node_modules\next\dist\compiled\webpack\bundle4.js:56716:26)
        at C:\Users\sdqui\Desktop\next-pwa\examples\custom-worker\node_modules\next\dist\compiled\webpack\bundle4.js:56735:7
        at arrayIterator (C:\Users\sdqui\Desktop\next-pwa\examples\custom-worker\node_modules\next\dist\compiled\neo-async\async.js:1:14270)
        at timesSync (C:\Users\sdqui\Desktop\next-pwa\examples\custom-worker\node_modules\next\dist\compiled\neo-async\async.js:1:5037)
        at Object.eachLimit (C:\Users\sdqui\Desktop\next-pwa\examples\custom-worker\node_modules\next\dist\compiled\neo-async\async.js:1:14216)
        at emitFiles (C:\Users\sdqui\Desktop\next-pwa\examples\custom-worker\node_modules\next\dist\compiled\webpack\bundle4.js:56617:13)
        at C:\Users\sdqui\Desktop\next-pwa\examples\custom-worker\node_modules\next\dist\compiled\webpack\bundle4.js:36508:26
        at FSReqCallback.oncomplete (fs.js:184:5) {
      code: 'ERR_INVALID_ARG_TYPE'
    }
    

    How To Reproduce

    run build with a custom worker worker/index.js

    Additional Context

    This also happens with any of the examples that include a custom worker as well, I pulled the repo and tried to build:

    • Custom worker
    • cache on front end
    • web push

    and was met with the same error

    I am attempting to build on a windows 10 machine using node 14.15.1 and npm 6.14.8

    I can provide additional info if needed, I saw that there was a similar issue to this one in #167

    bug fixed 
    opened by SamuelQuinones 14
  • How can I avoid all API request from being cached.

    How can I avoid all API request from being cached.

    I tried something from issue #46

    But it didn't help. I updated the regex to /\/api\/.*/g

    runtimeCaching: [
      ...
      {
        urlPattern: /\/api\/.*/g,
        handler: "NetworkFirst",
      },
      ...
    
    ]
    
    

    It would be helpful if I could exclude all network request matching regex /\/api\/.*/g Thanks.

    done 
    opened by dreamer01 13
  • Wrong path in precaching from workbox

    Wrong path in precaching from workbox

    When I visit my exported site (by locally serving the /out directory) I get this error:

    workbox-07643d7a.js:1 Uncaught (in promise) bad-precaching-response: bad-precaching-response :: [{"url":"http://localhost:3000/public/pwa/android-chrome-144x144.png","status":404}]
        at D (http://localhost:3000/workbox-07643d7a.js:1:11361)
        at async Promise.all (index 0)
        at async D.install (http://localhost:3000/workbox-07643d7a.js:1:10780)
    

    It seems to be looking in the /public/pwa/ directory for the icons when they are in fact in the `/pwa/ directory.

    My manifest.json is also in the /pwa/ directory and looks like this:

    {
      "name": "Name",
      "short_name": "Name",
      "description": "description",
      "dir": "auto",
      "lang": "en-US",
      "display": "standalone",
      "orientation": "any",
      "start_url": "/?homescreen=1",
      "background_color": "#fff",
      "theme_color": "#000",
      "icons": [
        {
          "src": "/pwa/android-chrome-36x36.png",
          "sizes": "36x36",
          "type": "image/png"
        },
       ...
      ]
    }
    

    How come this it's looking for icons in the starting in public?

    Many thanks for any advice?

    I'm using version 2..1.2 of this module with next 9.2.1

    opened by bravokiloecho 13
  • OAuth flow breaks on Safari (iOS and MacOS) in PWA

    OAuth flow breaks on Safari (iOS and MacOS) in PWA

    Summary

    When I try to use Google OAuth with next-auth and add next-pwa to my app, it doesn't work in Safari for Mac and iOS devices. The user is able to enter Google credentials, but when Google attempts to redirect back to the app next-auth returns an error.

    How To Reproduce

    I am using next-auth with the progressive-web-app. I created a repo which is the simplest combination of these two examples.

    1. Visit pwa-sage.vercel.app from an iPhone or Mac
    2. Click on the Sign In button in the top right corner
    3. Enter Google credentials and try to login
    4. See error

    Expected Behaviors

    You will not be able to login from an iOS or Mac device

    Screenshots

    next-auth generates this error ONLY when attempting to authenticate in a Mac or iOS device.

    [GET] /api/auth/callback/google?state=a18d41d8...bd&code=4%2...lHx1JC-fg&scope=email+profile+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&authuser=0&prompt=none
    12:57:40:47
    Status: 302
    Duration: 3.58ms
    Memory Used: 108 MB
    ID: l...d-160...1-79c...4
    User Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 14_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.1 Mobile/15E148 Safari/604.1 2020-12-12T17:57:40.487Z	a...c-690c-4ac7-b...7-f8...82	ERROR	[next-auth][error][callback_oauth_error] Error: Invalid state returned from oAuth provider
        at /var/task/node_modules/next-auth/dist/server/lib/oauth/callback.js:46:27
        at Generator.next (<anonymous>)
        at asyncGeneratorStep (/var/task/node_modules/next-auth/dist/server/lib/oauth/callback.js:26:103)
        at _next (/var/task/node_modules/next-auth/dist/server/lib/oauth/callback.js:28:194)
        at /var/task/node_modules/next-auth/dist/server/lib/oauth/callback.js:28:364
        at new Promise (<anonymous>)
        at /var/task/node_modules/next-auth/dist/server/lib/oauth/callback.js:28:97
        at /var/task/node_modules/next-auth/dist/server/lib/oauth/callback.js:143:17
        at /var/task/node_modules/next-auth/dist/server/routes/callback.js:58:31
        at Generator.next (<anonymous>) 
    https://next-auth.js.org/errors#callback_oauth_error
    

    photo_2020-12-12_17-55-22

    Everything that I've read points that the issue is caused by PWA and not the next-auth or my implementation of next-auth.

    Additional Context

    I've already asked in other repos about this issue, see here, but I'm still looking for a solution.

    I don't mind completely disabling everything related to next-pwa in iOS and Mac devices if that means having my OAuth work and still have PWA for the other devices.

    bug fixed 
    opened by diegoramosxyz 13
  • How can i prevent import duplicated files ?

    How can i prevent import duplicated files ?

    I use the next-optimized-images module who convert to webp on the fly all my images.

    The problem is the service worker import twice file.. like this : Capture d’écran 2020-04-30 à 15 35 57 the .jpg and the .webp version

    I would like to reduce the size of cache data and import all my images, except .wepb

    In my next.config.js I tried something like that:

    module.exports = withPlugins(
      [
        [
          withPWA,
          {
            pwa: {
              dest: "public",
              disable: process.env.NODE_ENV === "development",
              publicExcludes: ["([a-zA-Z0-9\\s_\\\\.\\-\\(\\):])+(.webp)$"]
            }
          }
        ],
        [...]
      ],
      nextConfig
    );
    

    But it seems it doesn’t work.

    However I tested my regex expression and it works well here: https://regex101.com/r/CRiDxt/1

    Someone would have an idea to solve my problem ? Thank you everyone

    done 
    opened by flosrn 13
  • `/_offline` not shown when offline

    `/_offline` not shown when offline

    Summary

    When offline, the cached pages work fine but when you visit an new (uncached) page, the /_offline page doesn't show up, instead the default chrome error page is shown.

    Versions

    • next-pwa: ^5.2.15
    • next: ^10.2.0

    How To Reproduce

    Steps to reproduce the behavior:

    1. Go to https://maximousblk-git-offline-maximousblk.vercel.app
    2. let the service register
    3. go offline (dev tools > application > service workers > offline)
    4. go to a page that wasn't cached on the first load (/posts/deno-for-javascript-beginners)

    source code at https://github.com/maximousblk/maximousblk.now.sh/pull/59 deployment at https://maximousblk-git-offline-maximousblk.vercel.app

    Expected Behavior

    Should show the custom offline page

    image

    Actual Behavior

    Shows Google Chrome's default offline page

    image

    Additional Context

    n/a

    bug fixed 
    opened by maximousblk 11
  • Application is not preaching and not working on offline with base path

    Application is not preaching and not working on offline with base path

    Hi,

    I am using basepath in next JS Application but deploying the Application on server I am not using any subdomain, instead I am replacing base path with empty string to access the pages / assets (this is my project requirement). While running the application on browser the index.html is cached within the defined based path on next JS (ex:start-url:http://localhost:4001 as /base-path which is resolving index.html ). When I try to run my application without base-path it's not working on offline mode.

    My PWA config:

    {
    basePath,
    pwa: {
            dest: `public`,
            register: true,
            skipWaiting: true,
            subdomainPrefix: `${basePath}/`,
            buildExcludes: [/middleware-manifest.json$/],
        }  
    }
    

    My next and PWA Version:

     "next": "12.0.4",
        "next-pwa": "5.4.1",
    

    My server code to replace base path:

    if(uri.includes('/base-path')) {
            req.url = '/';
       }
       
         if (!uriLastPart.includes("htm")) {
           if (uriLastPart.includes('.')) {
               req.url = uri.replace('corp-static/', "");
           }
       }
    
    
    Please help me with this. 
    
    opened by developerajendra 0
  • Page does not work offline -> Manifest Installability Error

    Page does not work offline -> Manifest Installability Error

    Summary

    I am facing PWA install issues with next-pwa

    For my root app location, it works fine and I can see the install button in the address bar. Once I navigate to another page and the URL changes. After that, if I hit refresh the error shows in the manifest.

    Any ideas on how to tackle this?

    CleanShot 2022-01-11 at 23 28 50

    Versions

    • next-pwa: 5.4.0
    • next: 10.2.3

    How To Reproduce

    Here is my manifest file

    { "theme_color": "#01805E", "background_color": "#F6F6F7", "display": "standalone", "start_url": "/", "name": "WhatsApp Inbox", "short_name": "WhatsApp Inbox", "icons": [ { "src": "/icon-192x192.png", "sizes": "192x192", "type": "image/png", "purpose": "any" }, { "src": "/icon-256x256.png", "sizes": "256x256", "type": "image/png", "purpose": "any" }, { "src": "/icon-384x384.png", "sizes": "384x384", "type": "image/png", "purpose": "any" }, { "src": "/icon-512x512.png", "sizes": "512x512", "type": "image/png", "purpose": "any" } ] }

    And the next.config.js -> https://gist.github.com/mayurc137/2ee7a2003da8c480332e91526b080ba6

    Expected Behaviors

    No matter which sub URL I visit for my app eg. https://app.com/workspace or https://app.com/account or https://app.com the install button should work and the manifest should not throw an error

    Additional Context

    I have also enabled offline support by adding _offline.tsx file to the pages directory

    bug 
    opened by mayurc137 0
  • SWC Support?

    SWC Support?

    Summary

    Are there any plans on upgrading to SWC?

    bug 
    opened by alex-cory 3
  • Caching data from server api

    Caching data from server api

    Hi, how to disable caching specific data from "getServerSideProps". In my case i am getting old data but after refreshing page i'm getting latest data. But network tabs shows both of them. Screen Shot 2021-12-28 at 14 24 27 I want to keep only last data because it's dynamic always. I couldn't find any useful data from net so decided to ask here. Thanks.

    opened by mirik999 1
  • Compatibility with old browsers

    Compatibility with old browsers

    Hi guys

    We need our project to be supported on old browsers. All the code is compatible with Chrome 30+ except Next PWA script in the main.js output file. `// CONCATENATED MODULE: ./node_modules/next-pwa/register.js

    if (typeof window !== 'undefined' && 'serviceWorker' in navigator && typeof caches !== 'undefined') { if (true) { caches.has('start-url').then(function(has) { if (!has) { caches.open('start-url').then(c => c.put('/', new Response('', {status: 200}))) } }) }`

    As you can see, the arrow functions were not converted by the babel. Although I have used arrow functions in the entire project, there are no arrow functions in other places in the output js file. It seems the Next PWA is just skipping babel.

    The project is written in typescript [email protected] [email protected]

    opened by mmdalix 3
  • No Controle over caching data from public folder

    No Controle over caching data from public folder

    Hello Everyone.. I am Working on this website for pwa implementation

    https://d24qi6xrnoiehb.cloudfront.net/

    i am using pwa-next module

    and using next.config.js as

    const withPWA = require('next-pwa')({
      pwa: {
        dest: 'public',
        register: true,
        skipWaiting: true,
        runtimeCaching,
        // buildExcludes: [/public/$/],
        publicExcludes: ['!/public/**/'],
        // disable: process.env.NODE_ENV === 'development',
      },
    });
    
    

    now the problem is that i have large files in the public directry as shown in the image below:

    image

    when i deploy and open this for first time . it load almost 200 mb data in the cache memory.

    image

    and it takes around 20 min to show this option for download app

    image

    how can i fix it ?

    opened by SonuKumar81800 0
  • Runtime Cache is not working

    Runtime Cache is not working

    Summary

    Hi I'm new to PWA / Workbox. So I'm not sure if it is a bug or not. I just want to ask a question if I'm configuring my next-pwa correctly or not.

    So I want to cache an api from my Backend service that hosted on different domain. I cloned cache.js and add my own entry. However it seems that it doesn't use my configuration at all. Please clone this repository : https://github.com/fawwaz/next-pwa-demo

    Versions

    • next-pwa: 5.4.4
    • next: 11.1.3

    How To Reproduce

    Steps to reproduce the behavior:

    1. Clone https://github.com/fawwaz/next-pwa-demo
    2. run yarn in the root
    3. yarn build && yarn start
    4. open localhost:3000
    5. Click the button to trigger api request.
    6. Set the network to offline
    7. Click the button again to trigger api request
    8. Service worker failed to respond it with cached request.

    Expected Behaviors

    Service worker should intercept/respond the request using cached response from previous request.

    Link to minimal reproduce setup repository if any.

    https://github.com/fawwaz/next-pwa-demo

    Screenshots

    Demo

    https://user-images.githubusercontent.com/1295143/147207322-309a1b19-bc41-4a0c-be7f-3e62aa85b304.mp4

    Additional Context

    file: next.config.js

    const withPWA = require("next-pwa");
    const runtimeCaching = require("./config/cache");
    
    module.exports = withPWA({
      pwa: {
        dest: "public",
        register: true,
        skipWaiting: true,
        mode: "development",
        disable: process.env.NODE_ENV !== "production",
        runtimeCaching,
      },
    });
    

    file: cache.js

    module.exports = [
      {
        urlPattern: "https://60a3771d7c6e8b0017e26fe5.mockapi.io/todo",
        handler: "StaleWhileRevalidate",
        options: {
          cacheName: "todo",
          expiration: {
            maxEntries: 4,
            maxAgeSeconds: 60, // 60 seconds
          },
        },
      },
    ];
    
    
    bug 
    opened by fawwaz 0
  • PWA not working on android device.

    PWA not working on android device.

    I run your next-9 example, and deployed on vercel, pwa is working fine on PC, but not working on my android device, neither android chrome nor samsung internet.

    Is there any known issue on android device?

    Here is the link I deployed:

    https://next-pwa-test-six.vercel.app/

    bug 
    opened by jiaxu09 0
  • Firebase Authentication Session management with service workers

    Firebase Authentication Session management with service workers

    Session management with service workers https://firebase.google.com/docs/auth/web/service-worker-sessions

    I'm sorry if this is not the right place to write this. Do you have a sample of integrating this library with Firebase authentication being handled by a service worker?

    I know that I can apply my own processing to worker/index.js.

    In the Firebase example, the process of inserting a token into the Authentication header is written. However, every so often the header is empty.

    Does anyone else have this working well?

    My code. worker/index.js

    import * as firebase from 'firebase/app';
    import 'firebase/auth';
    
    // Initialize the Firebase app in the service worker script.
    firebase.initializeApp({
      apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
      authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
      databaseURL: process.env.NEXT_PUBLIC_FIREBASE_DATABASE_URL,
      projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
      storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
      messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
      appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
      measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID,
    });
    
    /**
     * Returns a promise that resolves with an ID token if available.
     * @return {!Promise<?string>} The promise that resolves with an ID token if
     *     available. Otherwise, the promise resolves with null.
     */
    const getIdToken = () => {
      return new Promise((resolve, reject) => {
        const unsubscribe = firebase.auth().onAuthStateChanged((user) => {
          unsubscribe();
          if (user) {
            user.getIdToken().then((idToken) => {
              resolve(idToken);
            }, (error) => {
              resolve(null);
            });
          } else {
            resolve(null);
          }
        });
      });
    };
    
    const getOriginFromUrl = (url) => {
      // https://stackoverflow.com/questions/1420881/how-to-extract-base-url-from-a-string-in-javascript
      const pathArray = url.split('/');
      const protocol = pathArray[0];
      const host = pathArray[2];
      return protocol + '//' + host;
    };
    
    // Get underlying body if available. Works for text and json bodies.
    const getBodyContent = (req) => {
      return Promise.resolve().then(() => {
        if (req.method !== 'GET') {
          if (req.headers.get('Content-Type').indexOf('json') !== -1) {
            return req.json()
              .then((json) => {
                return JSON.stringify(json);
              });
          } else {
            return req.text();
          }
        }
      }).catch((error) => {
        // Ignore error.
      });
    };
    
    self.addEventListener('fetch', (event) => {
      /** @type {FetchEvent} */
      const evt = event;
    
      const requestProcessor = (idToken) => {
        let req = evt.request;
        let processRequestPromise = Promise.resolve();
        // For same origin https requests, append idToken to header.
        if (self.location.origin == getOriginFromUrl(evt.request.url) &&
            (self.location.protocol == 'https:' ||
             self.location.hostname == 'localhost' || 
             self.location.hostname == 'penguin.linux.test') &&
            idToken) {
          // Clone headers as request headers are immutable.
          const headers = new Headers();
          req.headers.forEach((val, key) => {
            headers.append(key, val);
          });
          // Add ID token to header.
          headers.append('Authorization', 'Bearer ' + idToken);
          processRequestPromise = getBodyContent(req).then((body) => {
            try {
              req = new Request(req.url, {
                method: req.method,
                headers: headers,
                mode: 'same-origin',
                credentials: req.credentials,
                cache: req.cache,
                redirect: req.redirect,
                referrer: req.referrer,
                body,
                // bodyUsed: req.bodyUsed,
                // context: req.context
              });
            } catch (e) {
              // This will fail for CORS requests. We just continue with the
              // fetch caching logic below and do not pass the ID token.
            }
          });
        }
        return processRequestPromise.then(() => {
          return fetch(req);
        });
      };
      // Fetch the resource after checking for the ID token.
      // This can also be integrated with existing logic to serve cached files
      // in offline mode.
      evt.respondWith(getIdToken().then(requestProcessor, requestProcessor));
    });
    
    self.addEventListener('activate', (event) => {
      event.waitUntil(clients.claim());
    });
    
    bug 
    opened by 345ml 0
  • Introduce an cacheStartUrl configuration

    Introduce an cacheStartUrl configuration

    With cacheStartUrl users can decide if they want to cache or not startUrl. It is the same as dynamicStartUrl but with dynamicStartUrl serviceWorker will send a request extra.

    opened by shrashiti 0
Owner
Wei Wang
Software Development Engineer & AI & React - Linkedin: www.linkedin.com/in/weiwio
Wei Wang
A Next.js plugin for embedding optimized images.

Next.js plugin for embedding optimized images. Features import png/jpg images output to webp format resize to multiple screen sizes and densities opti

Humaans 186 Jan 16, 2022
Next.js plugin to transpile code from node_modules

Next.js + Transpile node_modules Transpile modules from node_modules using the Next.js Babel configuration. Makes it easy to have local libraries and

Pierre de la Martinière 817 Jan 10, 2022
Next SEO is a plug in that makes managing your SEO easier in Next.js projects.

Next SEO Next SEO is a plugin that makes managing your SEO easier in Next.js projects. Pull requests are very welcome. Also make sure to check out the

Gary Meehan 4.3k Jan 21, 2022
next-useragent parses browser user-agent strings for next.js

next-useragent ⚠️ Version 2 of this library will work only with Next.js 9. If you're using Next.js 6-8 you can use previous versions. ⚠️ next-useragen

Tsuyoshi Tokuda 269 Jan 6, 2022
Vulcan Next helps you build GraphQL-based applications with Next.js

Vulcan Next Vulcan Next helps you build GraphQL-based applications with Next.js. What's in the box? Vulcan Next provides: A production-grade Next.js +

null 6 Dec 29, 2021
A plugin to generate terraform configuration for Nextjs 8 and 9

Terraform nextjs plugin A plugin to generate terraform configuration from nextjs pages The reason Nextjs supports serverless pages, where it creates f

Emanuele 47 Sep 30, 2021
Language detector that works universally (browser + server) - Meant to be used with a universal framework, such as Next.js

Universal Language Detector Language detector that works universally (browser + server) On the server, will rely on "cookies > accept-language header"

Unly 65 Dec 5, 2021
Universal dynamic routes for Next.js

Dynamic Routes for Next.js Easy to use universal dynamic routes for Next.js Express-style route and parameters matching Request handler middleware for

null 2.4k Jan 14, 2022
Extended Next.js server with pkg support

Next-Pkg is a package for compiling your Next.js project with pkg. This is how you can deploy your Next.js apps on enviroments without node installed!

Federico Miras 55 Aug 30, 2021
Apollo HOC for Next.js

next-with-apollo Apollo HOC for Next.js. For Next v9 use the latest version. For Next v6-v8 use the version 3.4.0. For Next v5 and lower go here and u

Luis Alvarez D. 751 Jan 13, 2022
Cookie serializer and deserializer library for next.js

next-cookie Cookie serializer and deserializer library for next.js. Installation $ npm install next-cookie Usage HOCs The cookies are read and write

Tsuyoshi Tokuda 170 Jan 17, 2022
A static site generator with markdown + react for Next.js

nextein A static site generator based in Next.js Site | Documentation | Guides What is it? nextein is a wrapper around next.js that allows you to writ

Max Fierro 854 Jan 19, 2022
Easily add a blog to any next.js based project.

next-mdx-blog Easy blog for next.js next-mdx-blog enables you to easily add a blog to any next.js based project. EXAMPLE: http://hipstersmoothie.com/b

Andrew Lisowski 66 Jan 9, 2022
⚡ Deploy your Next.js apps on AWS [email protected] via Serverless Components

Serverless Next.js Component A zero configuration Next.js 9.0 serverless component for AWS [email protected] aiming for full feature parity. Please review f

null 3.1k Jan 14, 2022
Simple promise-based session middleware for Next.js, micro, Express, and more

next-session Simple promise-based session middleware for Next.js. Also works in micro or Node.js HTTP Server, Express, and more. Project status: While

Hoang 229 Jan 14, 2022
🛠 Next.js stateless session utility using signed and encrypted cookies to store data

next-iron-session ?? Next.js and Express (connect middleware) stateless session utility using signed and encrypted cookies to store data This Next.js,

Vincent Voyer 1.2k Jan 16, 2022
The TypeScript-ready, minimal router and middleware layer for Next.js, Micro, Vercel, or Node.js http/http2

next-connect The smol method routing and middleware for Next.js (also works in other frameworks). Powered by trouter. Features Compatible with Express

Hoang 903 Jan 15, 2022
Authentication for Next.js

NextAuth.js Authentication for Next.js Open Source. Full Stack. Own Your Data. Overview NextAuth.js is a complete open source authentication solution

NextAuth.js 8.6k Jan 14, 2022
Effortless deployment to AWS and GitHub Pages for Next.js apps 🚀

Next Deploy Effortless deployment to AWS and GitHub Pages for Next.js apps ?? Table of Contents Getting Started Features Background CLI Distributed De

Egor Philippov 39 Jan 3, 2022