Como criar vários Progressive Web Apps no mesmo domínio

Como criar vários PWAs, aproveitando o mesmo nome de domínio, para que o usuário saiba que eles pertencem à mesma organização ou serviço.

Chase Phillips
Demián Renzulli
Demián Renzulli
Matt Giuca
Matt Giuca

No post do blog sobre Progressive Web Apps em sites de várias origens, Demian discutiu os desafios que os sites criados em várias origens enfrentam ao tentar criar um único Progressive Web App que os engloba.

Um exemplo desse tipo de arquitetura é um site de e-commerce em que:

  • A página inicial está em https://www.example.com.
  • As páginas de categoria são hospedadas em https://category.example.com.
  • As páginas de detalhes do produto em https://product.example.com.

Como discutido no artigo, a política de mesma origem impõe várias restrições, impedindo o compartilhamento de service workers, caches e permissões entre origens. Por isso, recomendamos evitar esse tipo de configuração. Para quem já tem sites criados dessa forma, considere migrar para uma arquitetura de site de origem única sempre que possível.

Diagrama mostrando um site dividido em várias origens e mostrando que essa técnica não é recomendada ao criar PWAs.
Evite usar origens diferentes para seções do mesmo site ao tentar criar um app Web progressivo unificado.

Nesta postagem, analisamos o caso oposto: em vez de um único PWA em origens diferentes, vamos analisar o caso de empresas que querem fornecer vários PWAs, usando o mesmo nome de domínio, e informar ao usuário que esses PWAs pertencem à mesma organização ou serviço.

Como você deve ter notado, estamos usando termos diferentes, mas relacionados, como domínios e origens. Antes de continuar, vamos revisar estes conceitos.

Termos técnicos

  • Domínio: qualquer sequência de identificadores, conforme definido no Sistema de Nomes de Domínio (DNS). Por exemplo, com e example.com são domínios.
  • Nome do host: uma entrada DNS que é resolvida para pelo menos um endereço IP. Por exemplo: www.example.com seria um nome de host, example.com poderia ser um nome de host se tivesse um endereço IP, e com nunca seria resolvido em um endereço IP e, portanto, nunca poderia ser um nome de host.
  • Origem: uma combinação de esquema, nome do host e (opcionalmente) porta. Por exemplo, https://www.example.com:443 é uma origem.

Como o nome indica, a política de mesma origem impõe restrições às origens. Portanto, vamos nos referir ao termo ao longo do artigo. No entanto, vamos usar "domínios" ou "subdomínios" de vez em quando para descrever a técnica usada e criar as diferentes "origens".

Em alguns casos, você pode querer criar apps independentes, mas ainda identificá-los como pertencentes à mesma organização ou "marca". Reutilizar o mesmo nome de domínio é uma boa maneira de estabelecer essa relação. Exemplo:

  • Um site de e-commerce quer criar uma experiência independente para permitir que os vendedores gerenciem o inventário, garantindo que eles entendam que ele pertence ao site principal em que os usuários compram produtos.
  • Um site de notícias esportivas quer criar um app específico para um grande evento esportivo, para que os usuários recebam estatísticas sobre as competições favoritas deles por notificações e instalem o app como um Progressive Web App, garantindo que os usuários reconheçam que ele foi criado pela empresa de notícias.
  • Uma empresa quer criar apps separados de chat, e-mail e agenda e quer que eles funcionem como apps individuais, vinculados ao nome da empresa.
Evite usar origens diferentes para seções do mesmo site ao tentar criar um app da Web progressivo unificado.
A empresa proprietária de example.com quer oferecer três apps ou PWAs independentes, usando o mesmo nome de domínio para estabelecer a relação entre eles.

Como usar origens separadas

A abordagem recomendada em casos como esses é para cada app conceitualmente distinto ativo na própria origem.

Se você quiser usar o mesmo nome de domínio dentro de todos eles, use subdomínios. Por exemplo, uma empresa que oferece vários apps ou serviços de Internet pode hospedar um app de e-mail em https://mail.example.com e um app de agenda em https://calendar.example.com, além de oferecer o serviço principal da empresa em https://www.example.com. Outro exemplo é um site de esportes que quer criar um app independente totalmente dedicado a um evento esportivo importante, como um campeonato de futebol em https://footballcup.example.com, que os usuários podem instalar e usar independentemente do site esportivo principal, hospedado em https://www.example.com. Essa abordagem também pode ser útil para plataformas que permitem aos clientes criar apps independentes próprios sob a marca da empresa. Por exemplo, um app que permite que os comerciantes criem os próprios PWAs em https://merchant1.example.com, https://merchant2.example.com etc.

O uso de origens diferentes garante o isolamento entre os apps, o que significa que cada um deles pode gerenciar diferentes recursos do navegador de maneira independente, incluindo:

  • Instalabilidade: cada app tem o próprio manifesto e oferece a própria experiência de instalação.
  • Armazenamento: cada app tem seus próprios caches, armazenamento local e, basicamente, todas as formas de armazenamento local do dispositivo, sem compartilhá-los com os outros.
  • Workers de serviço: cada app tem o próprio worker de serviço para os escopos registrados.
  • Permissões: as permissões também têm escopo por origem. Graças a isso, os usuários vão saber exatamente para qual serviço estão concedendo permissões, e recursos como notificações serão atribuídos corretamente a cada app.

Criar esse nível de isolamento é o mais desejável no caso de uso de vários PWAs independentes. Por isso, recomendamos essa abordagem.

Se os apps em subdomínios quiserem compartilhar dados locais entre si, eles ainda poderão fazer isso por cookies ou, para cenários mais avançados, é possível considerar a sincronização do armazenamento por meio de um servidor.

ALT_TEXT_HERE
Criar diferentes PWAs com origens distintas usando subdomínios é uma prática recomendada.

Usando a mesma origem

A segunda abordagem é criar diferentes PWAs na mesma origem. Isso inclui os seguintes cenários:

Caminhos não sobrepostos

Vários PWAs ou "apps da Web" conceituais, hospedados na mesma origem, com caminhos não sobrepostos. Exemplo:

  • https://example.com/app1/
  • https://example.com/app2/

Caminhos aninhados/sobrepostos

Várias PWAs na mesma origem, com um escopo aninhado dentro do outro:

  • https://example.com/ (o "app externo")
  • https://example.com/app/ (o "app interno")

A API do worker de serviço e o formato de manifesto permitem fazer qualquer uma das ações acima, usando o escopo no nível do caminho. No entanto, nos dois casos, o uso da mesma origem apresenta muitos problemas e limitações. A raiz disso tudo ocorre porque o navegador não os considera totalmente "apps" distintos. Portanto, essa abordagem não é recomendada.

ALT_TEXT_HERE
Não é recomendável usar caminhos (sobrepostos ou não) para fornecer dois PWAs independentes ("app1", "app2") com a mesma origem.

Na próxima seção, vamos analisar esses desafios em mais detalhes e o que pode ser feito se usar origens separadas não for uma opção.

Desafios para vários PWAs de mesma origem

Confira alguns problemas práticos comuns às duas abordagens de mesma origem:

  • Armazenamento:cookies, armazenamento local e todas as formas de armazenamento local do dispositivo são compartilhados entre os apps. Por esse motivo, se o usuário decidir limpar os dados locais de um app, todos os dados da origem serão excluídos. Não há como fazer isso para um único app. O Chrome e alguns outros navegadores vão pedir ativamente que os usuários limpem os dados locais ao desinstalar um dos apps, e isso também afetará os dados dos outros apps na origem. Outro problema é que os apps também precisam compartilhar a cota de armazenamento, o que significa que, se um deles ocupar muito espaço, o outro será afetado negativamente.
  • Permissões: as permissões do navegador estão vinculadas à origem. Isso significa que, se o usuário conceder uma permissão a um app, ela será aplicada a todos os apps dessa origem simultaneamente. Isso pode parecer uma coisa boa (não precisar pedir uma permissão várias vezes), mas lembre-se: se o usuário bloquear a permissão para um app, ele impedirá que os outros solicitem essa permissão ou usem esse recurso. Mesmo que as permissões do navegador precisem ser concedidas apenas uma vez por origem, as permissões no nível do sistema precisam ser concedidas uma vez por app, mesmo que vários apps apontem para a mesma origem.
  • Configurações do usuário:as configurações também são definidas por origem. Por exemplo, se dois apps tiverem tamanhos de fonte diferentes e o usuário quiser ajustar o zoom em apenas um deles para compensar, ele não poderá fazer isso sem aplicar a configuração aos outros apps também.

Esses desafios dificultam a adoção dessa abordagem. No entanto, se você não puder usar uma origem separada (por exemplo, um subdomínio), como discutido na seção Como usar origens separadas, das duas opções de mesma origem que apresentamos, o uso de caminhos não sobrepostos é altamente recomendado, em vez de caminhos sobrepostos/aninhados.

Como mencionado, os desafios discutidos nesta seção são comuns às duas abordagens de mesma origem. Na próxima seção, vamos detalhar por que usar caminhos sobrepostos/aninhados é a estratégia menos recomendada.

Outros desafios para caminhos aninhados/sobrepostos

O problema adicional com a abordagem de caminhos sobrepostos/aninhados (em que https://example.com/ é o app externo e https://example.com/app/ é o app interno) é que todos os URLs no app interno serão considerados parte do app externo e do app interno.

Na prática, isso apresenta os seguintes problemas:

  • Promoção de instalação: se o usuário visitar o app interno (por exemplo, em um navegador da Web), quando o app externo já estiver instalado no dispositivo do usuário, o navegador não vai mostrar os banners promocionais de instalação, e o evento BeforeInstallPrompt não será acionado. O motivo é que o navegador vai verificar se a página atual pertence a um app que já está instalado e concluirá que sim. A solução alternativa para isso é instalar o app interno manualmente (com a opção de menu do navegador "Criar atalho") ou instalar o app interno antes do externo.
  • Notificação e a API Badging: se o app externo estiver instalado, mas o interno não, as notificações e os ícones provenientes do app interno serão atribuídos erroneamente ao app externo, que é o escopo mais próximo de um app instalado. Esse recurso funciona corretamente no caso em que os dois apps estão instalados no dispositivo do usuário.
  • Captura de links: o app externo pode capturar URLs que pertencem ao app interno. Isso é mais provável se o app externo estiver instalado, mas o app interno não. Da mesma forma, os links dentro do app externo que se conectam ao app interno não vão vincular a captura ao app interno, já que são considerados dentro do escopo do app externo. Além disso, no ChromeOS e no Android, se esses apps forem adicionados à Play Store (como atividades da Web confiáveis), o app externo vai capturar todos os links. Mesmo que o app interno esteja instalado, o SO ainda vai oferecer ao usuário a opção de abri-lo no app externo.

Conclusão

Neste artigo, analisamos diferentes maneiras pelas quais os desenvolvedores podem criar vários Progressive Web Apps relacionados entre si dentro do mesmo domínio.

Em resumo, é altamente recomendável usar uma origem diferente (por exemplo, usando subdomínios) para hospedar PWAs independentes. Hospedá-los na mesma origem apresenta muitos desafios, principalmente porque o navegador não os considerará totalmente como apps diferentes.

  • Origens separadas: recomendado
  • Mesma origem, caminhos não sobrepostos: não recomendado
  • Mesma origem, caminhos sobrepostos/aninhados: não recomendado

Se não for possível usar origens diferentes, use caminhos que não se sobrepõem (por exemplo, https://example.com/app1/ e https://example.com/app2/). É altamente recomendável usar caminhos aninhados ou sobrepostos, como https://example.com/ (para o app externo) e https://example.com/app/ (para o app interno).

Outros recursos

Agradecemos as avaliações e sugestões técnicas: Joe Medley, Dominick Ng, Alan Cutter, Daniel Murphy, Penny McLachlan, Thomas Steiner e Darwin Huang

Foto de Tim MossHolder no Unsplash (links em inglês)