Este plugin é desenvolvido com workbox e outras coisas boas.
Compartilhe seu incrível projeto PWA aqui
Características
next-i18next
blitz.config.js
).module.js
quando next.config.js
tem experimental.modern
definido como true
NOTA 1 -
next-pwa
versão 2.0.0+ deve funcionar apenas comnext.js
9.1+, e arquivos estáticos só devem ser servidos através do diretóriopublic
. Isso tornará as coisas mais simples.NOTA 2 - Se você encontrar o erro
TypeError: Cannot read property **'javascript' of undefined**
durante a construção, considere atualizar para webpack5 emnext.config.js
.
Se você é novo em
next.js
oureact.js
, você pode querer primeiro verificar o documento next.js ou next.js. Em seguida, comece com um exemplo simples ou um exemplo de aplicativo da web progressivo no repositório next.js.
yarn add next-pwa
Atualize ou crie next.config.js
com
const withPWA = require ( 'next-pwa' ) ( {
dest : 'public'
} )
module . exports = withPWA ( {
// next.js config
} )
Depois de executar next build
, isso irá gerar dois arquivos em seu public
: workbox-*.js
e sw.js
, que serão automaticamente veiculados estaticamente.
Se você estiver usando Next.js versão 9 ou mais recente, pule as opções abaixo e vá para a Etapa 2.
Se estiver usando Next.js anterior à versão 9, você precisará escolher uma opção abaixo antes de continuar para a Etapa 2.
Copie os arquivos para seu servidor de hospedagem de arquivos estáticos, para que possam ser acessados pelos seguintes caminhos: https://yourdomain.com/sw.js
e https://yourdomain.com/workbox-*.js
.
Um exemplo é usar o serviço de hospedagem Firebase para hospedar esses arquivos estaticamente. Você pode automatizar a etapa de cópia usando scripts no fluxo de trabalho de implantação.
Por motivos de segurança, você deve hospedar esses arquivos diretamente do seu domínio. Se o conteúdo for entregue usando um redirecionamento, o navegador se recusará a executar o service worker.
Quando uma solicitação HTTP for recebida, teste se esses arquivos são solicitados e, em seguida, retorne esses arquivos estáticos.
Exemplo 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' || / ^/(workbox|worker|fallback)-w+.js$ / . test ( pathname ) ) {
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 } ` )
} )
} )
A configuração a seguir não tem nada a ver com o plugin
next-pwa
e você provavelmente já os configurou. Caso contrário, vá em frente e configure-os.
Crie um arquivo manifest.json
em sua pasta public
:
{
"name" : " PWA App " ,
"short_name" : " App " ,
"icons" : [
{
"src" : " /icons/android-chrome-192x192.png " ,
"sizes" : " 192x192 " ,
"type" : " image/png " ,
"purpose" : " any maskable "
},
{
"src" : " /icons/android-chrome-384x384.png " ,
"sizes" : " 384x384 " ,
"type" : " image/png "
},
{
"src" : " /icons/icon-512x512.png " ,
"sizes" : " 512x512 " ,
"type" : " image/png "
}
],
"theme_color" : " #FFFFFF " ,
"background_color" : " #FFFFFF " ,
"start_url" : " / " ,
"display" : " standalone " ,
"orientation" : " portrait "
}
Adicione o seguinte em _document.jsx
ou _app.tsx
, em :
< 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 =" /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 " href =" /icons/touch-icon-iphone.png " />
< link rel =" apple-touch-icon " sizes =" 152x152 " href =" /icons/touch-icon-ipad.png " />
< link rel =" apple-touch-icon " sizes =" 180x180 " href =" /icons/touch-icon-iphone-retina.png " />
< link rel =" apple-touch-icon " sizes =" 167x167 " href =" /icons/touch-icon-ipad-retina.png " />
< link rel =" icon " type =" image/png " sizes =" 32x32 " href =" /icons/favicon-32x32.png " />
< link rel =" icon " type =" image/png " sizes =" 16x16 " href =" /icons/favicon-16x16.png " />
< link rel =" manifest " href =" /manifest.json " />
< link rel =" mask-icon " href =" /icons/safari-pinned-tab.svg " color =" #5bbad5 " />
< link rel =" shortcut icon " href =" /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/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/icons/apple-touch-icon.png " />
Dica: coloque a meta tag do cabeçalho
viewport
em_app.js
em vez de_document.js
se necessário.
< meta
name = 'viewport'
content = 'minimum-scale=1, initial-scale=1, width=device-width, shrink-to-fit=no, user-scalable=no, viewport-fit=cover'
/ >
Os fallbacks offline são úteis quando a busca falhou no cache e na rede, um recurso pré-armazenado em cache é servido em vez de apresentar um erro do navegador.
Para começar, basta adicionar uma página /_offline
como pages/_offline.js
ou pages/_offline.jsx
ou pages/_offline.ts
ou pages/_offline.tsx
. Então está tudo pronto! Quando o usuário estiver offline, todas as páginas que não estão armazenadas em cache retornarão para '/_offline'.
Use este exemplo para vê-lo em ação
next-pwa
ajuda você a pré-armazenar esses recursos em cache no primeiro carregamento e, em seguida, injetar um manipulador substituto no plug-in handlerDidError
em todas as configurações runtimeCaching
, para que os recursos pré-armazenados em cache sejam servidos quando a busca falhar.
Você também pode configurar precacheFallback.fallbackURL
em sua entrada de configuração runtimeCaching para implementar funcionalidade semelhante. A diferença é que o método acima é baseado no tipo de recurso, este método é baseado no padrão de URL correspondente. Se esta configuração for definida na entrada de configuração runtimeCaching, o substituto baseado no tipo de recurso será desabilitado automaticamente para este padrão de URL específico para evitar conflitos.
Existem opções que você pode usar para personalizar o comportamento deste plugin adicionando o objeto pwa
na próxima configuração em next.config.js
:
const withPWA = require ( 'next-pwa' ) ( {
dest : 'public'
// disable: process.env.NODE_ENV === 'development',
// register: true,
// scope: '/app',
// sw: 'service-worker.js',
//...
} )
module . exports = withPWA ( {
// next.js config
} )
false
disable: false
, para que ele gere service worker em dev
e prod
disable: true
para desabilitar completamente o PWAdev
, você pode definir disable: process.env.NODE_ENV === 'development'
true
false
quando você deseja lidar com o trabalhador do serviço de registro, isso pode ser feito em componentDidMount
do seu aplicativo raiz. você pode considerar o Register.js como exemplo.basePath
em next.config.js
ou /
/app
para que o caminho em /app
seja PWA enquanto outros não/sw.js
public
de serem pré-armazenados em cache.['!noprecache/**/*']
- isso significa que o comportamento padrão irá pré-armazenar em cache todos os arquivos dentro de sua pasta public
mas os arquivos dentro da pasta /public/noprecache
. Você pode simplesmente colocar os arquivos dentro dessa pasta para não pré-armazená-los em cache sem configurar isso.['!img/super-large-image.jpg', '!fonts/not-used-fonts.otf']
.next/static
(ou em sua compilação personalizada)[]
[/chunks/images/.*$/]
- Não pré-armazene arquivos em .next/static/chunks/images
(recomendo isso para funcionar com o plugin next-optimized-images
)true
true
cacheStartUrl
definido como true
/login
, é recomendado configurar esse URL redirecionado para a melhor experiência do usuário.undefined
dynamicStartUrlRedirect
definido como true
/_offline
como pages/_offline.js
e está tudo pronto, nenhuma configuração necessáriaobject
fallbacks.document
- rota substituta para documento (página), padrão para /_offline
se você criou essa páginafallbacks.image
- rota substituta para imagem, padrão para nenhumfallbacks.audio
- rota substituta para áudio, padrão para nenhumfallbacks.video
- rota substituta para vídeo, padrão para nenhumfallbacks.font
- rota substituta para fonte, padrão para nenhumnext/link
no front end. Confira este exemplo para obter algum contexto sobre por que isso foi implementado.false
""
- ou seja, padrão sem prefixo/subdomain
se o aplicativo estiver hospedado em example.com/subdomain
location.reload()
para atualizar o aplicativo.true
next-pwa
procura uma implementação de trabalhador personalizado para adicionar ao trabalhador de serviço gerado pela caixa de trabalho. Para obter mais informações, confira o exemplo do trabalhador personalizado.worker
next-pwa
usa workbox-webpack-plugin
, outras opções que também podem ser colocadas no objeto pwa
podem ser encontradas NA DOCUMENTAÇÃO para GenerateSW e InjectManifest. Se você especificar swSrc
, o plugin InjectManifest
será usado, caso contrário, GenerateSW
será usado para gerar o service worker.
next-pwa
usa um cache.js de tempo de execução padrão
Há uma grande chance de você querer personalizar suas próprias regras de cache de tempo de execução. Sinta-se à vontade para copiar o arquivo cache.js
padrão e personalizar as regras como desejar. Não se esqueça de injetar as configurações em sua configuração pwa
em next.config.js
.
Aqui está o documento sobre como escrever configurações de cache em tempo de execução, incluindo sincronização em segundo plano e recursos de atualização de transmissão e muito mais!
{command: 'doSomething', message: ''}
objeto quando postMessage
para o service worker. Para que no ouvinte ele possa realizar várias tarefas diferentes usando if...else...
.clean application cache
para reduzir alguns erros instáveis.runtimeCaching
como options.cacheableResponse.statuses=[200,302]
.sw.js
gerado para descobrir o que realmente está acontecendo.next-pwa
a gerar a construção de produção da caixa de trabalho especificando a opção mode: 'production'
na seção pwa
de next.config.js
. Embora next-pwa
gere automaticamente a construção de desenvolvimento da caixa de trabalho durante o desenvolvimento (executando next
) e a construção de produção da caixa de trabalho durante a produção (executando next build
e next start
). Você ainda pode querer forçar a construção de produção mesmo durante o desenvolvimento de seu aplicativo da web pelo seguinte motivo:self.__WB_DISABLE_DEV_LOGS = true
em seu worker/index.js
(crie um se não tiver um).userAgent
para determinar se os usuários estão usando Safari/iOS/MacOS ou alguma outra plataforma. A biblioteca ua-parser-js é uma boa amiga para esse propósito. MIT