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

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

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

Na postagem do blog sobre Apps Web Progressivos em sites de várias origens, Demian discutiu os desafios que sites criados em várias origens enfrentam ao tentar criar um único App Web Progressivo que abranja todos eles.

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.

Conforme 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 e, para quem já tem sites criados dessa forma, considerar a migração para uma arquitetura de site de origem única sempre que possível.

Diagrama mostrando um site dividido em várias origens e 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, vamos analisar o caso oposto: em vez de um único PWA em origens diferentes, vamos analisar o caso de empresas que querem fornecer vários PWAs, aproveitando o mesmo nome de domínio e informando 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 esses conceitos.

Termos técnicos

  • Domínio:qualquer sequência de rótulos 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 de 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 um esquema, um nome do host e (opcionalmente) uma porta. Por exemplo, https://www.example.com:443 é uma origem.

Como o nome sugere, a política de mesma origem impõe restrições às origens. Por isso, vamos usar esse termo na maior parte 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, talvez você queira 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 entendam que ele pertence ao site principal onde os usuários compram produtos.
  • Um site de notícias esportivas quer criar um app específico para um grande evento esportivo, permitir que os usuários recebam estatísticas sobre as competições favoritas por notificações e instalá-lo como um Progressive Web App, garantindo que os usuários o reconheçam como um app 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 PWA unificado.
A empresa proprietária de example.com quer fornecer 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 nesses casos é que cada app conceitualmente distinto fique na própria origem.

Se quiser usar o mesmo nome de domínio em 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, oferecendo o serviço principal da empresa em https://www.example.com. Outro exemplo é um site de esportes que quer criar um app independente dedicado a um evento esportivo importante, como um campeonato de futebol em https://footballcup.example.com, que os usuários podem instalar e usar de forma independente do site principal, hospedado em https://www.example.com. Essa abordagem também pode ser útil para plataformas que permitem que os clientes criem apps independentes com a marca da empresa. Por exemplo, um app que permite que os comerciantes criem PWAs próprios em https://merchant1.example.com, https://merchant2.example.com etc.

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

  • Instalabilidade:cada app tem o próprio manifesto e oferece uma experiência instalável.
  • 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.
  • Service workers:cada app tem um service worker próprio para os escopos registrados.
  • Permissões:as permissões também são definidas por origens. Assim, 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 grau de isolamento é o mais desejável no caso de uso de várias PWAs independentes. Por isso, recomendamos muito essa abordagem.

Se os apps em subdomínios quiserem compartilhar dados locais entre si, eles ainda poderão fazer isso usando cookies. Para cenários mais avançados, é possível sincronizar o armazenamento por um servidor.

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

Usar a mesma origem

A segunda abordagem é criar os 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 sobrepostos/aninhados

Vários PWAs na mesma origem, um dos quais tem um escopo aninhado dentro do outro:

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

A API Service Worker e o formato de manifesto permitem fazer qualquer uma das opções acima, usando o escopo no nível do caminho. No entanto, em ambos os casos, usar a mesma origem apresenta muitos problemas e limitações, cuja raiz decorre do fato de que o navegador não considera totalmente que esses são "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") na 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 isso, se o usuário decidir limpar os dados locais de um app, todos os dados da origem serão apagados. Não é possível fazer isso para um único app. O Chrome e alguns outros navegadores solicitam ativamente que os usuários limpem os dados locais ao desinstalar um dos apps, o que também afeta os dados dos outros apps na origem. Outro problema é que os apps também precisam compartilhar a cota de armazenamento. Isso 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 bom (não precisar pedir uma permissão várias vezes), mas lembre-se: se o usuário bloquear a permissão de um app, isso vai impedir que os outros peçam essa permissão ou usem esse recurso. Mesmo que as permissões do navegador só precisem ser concedidas 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, não será possível fazer isso sem aplicar a configuração aos outros apps também.

Esses desafios dificultam o incentivo a essa abordagem. No entanto, se não for possível usar uma origem separada (por exemplo, um subdomínio), conforme discutido na seção Usar origens separadas, das duas opções de mesma origem apresentadas, é altamente recomendável usar caminhos não sobrepostos 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 sobrepostos/aninhados

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 acessar o app interno (por exemplo, em um navegador da Web) quando o app externo já estiver instalado no dispositivo, 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 verifica se a página atual pertence a um app já instalado e conclui que sim. Para contornar isso, instale o app interno manualmente (na opção "Criar atalho" do menu do navegador) ou instale o app interno primeiro, antes do externo.
  • Notificação e a API Badging: se o app externo estiver instalado, mas o app interno não, as notificações e os ícones do app interno serão atribuídos erroneamente ao app externo (que é o escopo de inclusão mais próximo de um app instalado). Esse recurso funciona corretamente quando 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 é especialmente provável se o app externo estiver instalado, mas o interno não. Da mesma forma, os links no app externo que direcionam para o app interno não capturam links no 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 abrir no app externo.

Conclusão

Neste artigo, analisamos diferentes maneiras de os desenvolvedores criarem vários Progressive Web Apps relacionados entre si no mesmo domínio.

Em resumo, recomendamos usar uma origem diferente (por exemplo, subdomínios) para hospedar PWAs independentes. Hospedá-los na mesma origem apresenta muitos desafios, principalmente porque o navegador não considera totalmente que eles são apps distintos.

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

Se não for possível usar origens diferentes, use caminhos não sobrepostos (por exemplo, https://example.com/app1/ e https://example.com/app2/). Isso é altamente recomendado em vez de usar caminhos sobrepostos ou aninhados, como https://example.com/ (para o app externo) e https://example.com/app/ (para o app interno).

Outros recursos

Agradecemos muito pelas revisõ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