Um site, com momentos de reconhecimento de aplicativos.
O SDK é um aprimoramento progressivo opcional. Suas páginas ainda possuem conteúdo, roteamento, contas, carrinhos e regras de negócios. O shell nativo possui integrações de aplicativos e dispositivos cromados. O SDK passa mensagens pequenas e validadas entre os dois.
Não há nenhum serviço REST público SiteTo.App envolvido. Os sites não precisam de uma chave SiteTo.App e o SDK nunca deve conter credenciais de loja, segredos de clientes ou tokens de contas privilegiadas.
Títulos de páginas contextuais
Deixe uma página de checkout, conta ou artigo atualizar o cabeçalho nativo enquanto mantém o título do navegador correto.
Emblemas de navegação ao vivo
Envie um valor conhecido imediatamente ou leia um carrinho, uma caixa de entrada ou uma contagem de reservas a partir de um URL de mesma origem.
Navegação com reconhecimento de rota
Mantenha o item de navegação nativo ativo alinhado com páginas tradicionais e rotas de aplicativos de página única.
Eventos do ciclo de vida
Atualize o estado desatualizado do site quando o aplicativo for retomado, reconectado ou aberto a partir de uma notificação ou link direto.
Ações nativas
Use a planilha de compartilhamento do sistema, prompts de permissão, configurações e feedback tátil sutil quando compatível.
Comportamento seguro do navegador
Cada recurso tem um substituto de navegador documentado ou não operacional, para que a base de código de um site continue funcionando em qualquer lugar.
Um script, com versão explícita.
Adicione o script CDN a um site comum ou instale o pacote npm em um aplicativo incluído. Ambos expõem o mesmo comportamento e versão do protocolo.
<script
src="https://cdn.siteto.app/sdk/v1/sitetoapp.min.js"
defer
></script>import { SiteToApp } from '@sitetoapp/web-sdk';As versões principais residem no URL e no contrato do pacote. Adições ininterruptas podem ser enviadas dentro v1; métodos renomeados, cargas alteradas ou comportamento de fallback diferente exigem v2.
Detecte recursos, não agentes de usuário.
SiteToApp.ready() inicia um aperto de mão com o shell nativo e resolve para um AppContext. Ele também deve ser resolvido em um navegador normal, para que o código do aplicativo nunca seja interrompido enquanto aguarda uma ponte que não está presente.
const context = await SiteToApp.ready({ timeout: 1500 });
if (!context.available) {
// Normal browser: keep using your existing web behavior.
return;
}
await SiteToApp.page.setTitle('Order details');
await SiteToApp.navigation.setActive('orders');| Campo de contexto | Valor | Razão |
|---|---|---|
| disponível | booleano | Se um shell nativo completou um handshake válido. |
| plataforma | ios | andróide | rede | O tempo de execução ativo; nunca inferido do agente do usuário. |
| appVersion | corda | nulo | A versão nativa instalada do aplicativo, quando disponível. |
| sdkVersion | corda | A versão do SDK do site carregado. |
| protocolVersion | número | nulo | O contrato ponte negociado com o app. |
| capacidades | corda[] | Comandos suportados, como navigation.badge ou share. |
| colorScheme | luz | escuro | A aparência nativa atual. |
| safeArea | superior, direita, inferior, esquerda | Inserções em pixels CSS para layouts personalizados de tela inteira. |
context.capabilities quando o suporte varia de acordo com a versão do aplicativo instalado. As verificações da plataforma são o último recurso.Mantenha o cabeçalho nativo no contexto.
Uma página pode alterar o cabeçalho do aplicativo conforme os clientes navegam pelos produtos, artigos, seções da conta ou finalização da compra. Por padrão, setTitle atualiza o cabeçalho nativo e document.title portanto, o histórico do navegador também permanece útil.
// Update both the document title and the app header.
await SiteToApp.page.setTitle('Your cart');
// Change only the native header.
await SiteToApp.page.setTitle('Checkout', {
document: false,
native: true,
});
// Return to the title derived from the page or app configuration.
await SiteToApp.page.resetTitle();page.setLoading(boolean)Conecte uma transição de site ao indicador de carregamento do shell. O aplicativo ainda deve impor um tempo limite automático para que uma página não possa deixá-lo em execução para sempre.
page.setPullToRefresh(boolean)Desative puxar para atualizar para desenhar superfícies, mapas ou interações onde o gesto entra em conflito com o comportamento da página.
Mostre a contagem que importa agora.
Os itens de navegação usam IDs estáveis configurados no construtor SiteTo.App, como cart, inbox, ou bookings. Os rótulos podem mudar, mas esses IDs continuam sendo o contrato entre o site e o aplicativo.
Defina um valor conhecido
// Numbers are formatted by the native app: 100 becomes “99+”.
await SiteToApp.navigation.setBadge('cart', 3);
// Zero, null, or false hides the badge.
await SiteToApp.navigation.setBadge('cart', 0);
// Short status labels are also allowed.
await SiteToApp.navigation.setBadge('inbox', 'NEW');Atualizar a partir de um URL
Um observador busca no contexto do site, não em um serviço SiteTo.App separado. URLs relativos e de mesma origem são recomendados porque mantêm intactos os cookies normais do site e as regras de segurança.
const cartBadge = SiteToApp.navigation.watchBadge('cart', {
url: '/cart.js',
jsonPath: 'item_count',
interval: 30_000,
refreshOn: ['ready', 'resume', 'focus', 'urlchange'],
hideWhenZero: true,
stale: 'keep',
});
// Refresh after a local add-to-cart action.
await cartBadge.refresh();
// Stop fetching when this page no longer owns the badge.
cartBadge.stop();| Opção | Padrão | Comportamento |
|---|---|---|
| url | obrigatório | HTTPS ou URL relativo retornando JSON ou texto simples. |
| jsonPath | nenhum | Caminho de pontos como cart.item_count. Obrigatório quando o JSON não é o valor do selo. |
| intervalo | desabilitado | Intervalo de pesquisa em milissegundos, com mínimo de 15 segundos. |
| refreshOn | pronto, retomar | Qualquer combinação de pronto, currículo, foco e mudança de URL. |
| credenciais | mesma origem | Usa o modo de busca de credenciais do navegador. Solicitações de origem cruzada ainda exigem CORS. |
| tempo esgotado | 5000 | Tempo máximo de busca em milissegundos. |
| hideWhenZero | verdadeiro | Oculte o emblema quando o resultado mapeado for 0, nulo ou falso. |
| obsoleto | manter | Mantenha o último valor válido após um erro; claro é a alternativa. |
- Os valores numéricos são exibidos de 1 a 99; valores maiores usam o nativo 99+ treatment.
- Os valores de texto são cortados, limpos e limitados a quatro caracteres visíveis.
- A pesquisa é pausada enquanto o aplicativo está em segundo plano e é retomada com uma atualização imediata.
- Solicitações sobrepostas são canceladas; a resposta válida mais recente vence.
- Falhas de HTTP, análise e mapeamento são emitidas
sdk:errorsem quebrar a página.
Use o comportamento do dispositivo onde ele merece seu lugar.
As ações nativas devem melhorar um fluxo da web existente e não se tornar um requisito para o uso do site. Os prompts de permissão devem seguir uma ação clara do usuário e explicar primeiro seu valor na página.
await SiteToApp.share({
title: 'Spring collection',
text: 'These just arrived.',
url: window.location.href,
});
// Must be called from a user click or tap.
const permission = await SiteToApp.notifications.requestPermission();
// Use sparingly for confirmation, not decoration.
await SiteToApp.haptics.impact('light');Compartilhe com um substituto útil
Use a planilha de compartilhamento nativa no aplicativo, navigator.share quando disponível, um substituto da área de transferência após uma ação do usuário.
Mantenha o status da permissão simples
Retornar default, granted, denied, ou unsupported. Nunca exponha um push token bruto ao código da página.
Abra links externos deliberadamente
URLs aprovados internamente permanecem no aplicativo. Links HTTPS externos são abertos no navegador do sistema, a menos que a configuração do aplicativo indique o contrário.
Feedback físico com limite de taxa
A sensação tátil é ignorada quando não tem suporte e é limitada nativamente para evitar que uma página produza feedback perturbador repetido.
Deixe o site responder ao ciclo de vida do aplicativo.
Os eventos fluem do shell nativo para o SDK após a validação do esquema e da origem. Os manipuladores recebem cargas públicas mínimas e retornam uma função de cancelamento de assinatura para que sites baseados em componentes possam limpá-los.
const unsubscribe = SiteToApp.on('app:resume', () => {
cartBadge.refresh();
});
SiteToApp.on('navigation:reselect', ({ itemId }) => {
if (itemId === 'home') window.scrollTo({ top: 0, behavior: 'smooth' });
});
SiteToApp.on('notification:opened', ({ url }) => {
if (url) window.location.assign(url);
});
// Remove a listener when its owning component unmounts.
unsubscribe();app:resumeO aplicativo voltou ao primeiro plano. Atualize dados de páginas urgentes e emblemas assistidos.
app:pauseO aplicativo foi para segundo plano. Pause trabalhos caros que ainda não foram gerenciados pelo navegador.
navigation:reselectO usuário tocou novamente no item de navegação nativo atualmente ativo. Geralmente rola um feed para o topo.
route:openO shell recebeu um link direto confiável que o roteador da página deve manipular sem recarregar completamente.
notification:openedO usuário abriu uma notificação push. A carga útil contém um URL no aplicativo aprovado e metadados públicos opcionais.
network:changeA conectividade mudou entre online e offline. O navegador continua sendo a fonte da verdade para o sucesso real da busca.
appearance:changeA aparência nativa clara ou escura mudou. A carga útil inclui o novo esquema de cores.
sdk:errorUm inspetor, um comando de ponte ou uma validação de mensagem falhou. Destinado a diagnósticos, não a registros confidenciais.
O site deve permanecer um site.
Não estar dentro do aplicativo é um estado normal, não uma exceção. O SDK deve evitar ruídos de console e retornar resultados previsíveis quando sua contraparte nativa estiver ausente.
| Recurso | Comportamento normal do navegador |
|---|---|
| preparar | Resolve com available: false e platform: web após o tempo limite. |
| page.setTitle | Atualiza document.title quando o documento está habilitado; relatórios de entrega nativa falsos. |
| emblemas e estado do item | Não busque ou renderize por padrão. Retorno entregue: falso sem arremesso. |
| navigation.open | Usa location.assign, location.replace ou window.open de acordo com o destino. |
| navigation.back | Usa history.back quando o histórico do navegador está disponível. |
| compartilhar | Usa navigator.share e, em seguida, a área de transferência após um gesto do usuário. |
| notificações | Devoluções sem suporte; não substitui o sistema de notificação do navegador. |
| sensação ao toque | No-op seguro com entrega: falso. |
{ delivered: false, reason: 'not-in-app' }. Argumentos inválidos e negações nativas usam digitação SiteToAppError codes.Referência completa do método.
SiteToApp.ready(options?)Aguarde o handshake e resolva para o AppContext atual. Sempre resolve; um navegador normal retorna disponível: falso.
SiteToApp.getContext()Retorne a última plataforma negociada, versões, valores de área segura, esquema de cores e lista de capacidades.
SiteToApp.isAvailable()Relate de forma síncrona se uma ponte nativa validada está conectada no momento.
SiteToApp.page.setTitle(title, options?)Atualize document.title, o cabeçalho nativo ou ambos. Títulos vazios são rejeitados.
SiteToApp.page.setLoading(loading)Mostre ou oculte o indicador de carregamento do shell para uma transição de página ou ação de longa duração.
SiteToApp.page.setPullToRefresh(enabled)Ative ou desative o pull-to-refresh nativo para telas onde o gesto é apropriado.
SiteToApp.navigation.setBadge(itemId, value)Defina um emblema de item de navegação configurado. Zero, nulo e falso limpam.
SiteToApp.navigation.watchBadge(itemId, options)Busque e mapeie um valor de emblema em gatilhos de ciclo de vida ou em um intervalo controlado. Retorna controles de atualização e parada.
SiteToApp.navigation.setActive(itemId)Selecione um item de navegação nativa configurado sem navegar no site.
SiteToApp.navigation.syncWithLocation(rules)Observe o histórico do navegador e mantenha o item ativo alinhado às regras de correspondência de URL. Retorna uma função de cancelamento de assinatura.
SiteToApp.navigation.setItem(itemId, state)Atualize o rótulo, a visibilidade ou o estado ativado de um item configurado existente.
SiteToApp.navigation.open(url, options?)Abra um URL interno aprovado na visualização da web atual ou um URL HTTPS externo no navegador do sistema.
SiteToApp.navigation.back()Peça ao shell para voltar, acessando o histórico do navegador quando nenhuma rota nativa estiver disponível.
SiteToApp.share(data)Abra a planilha de compartilhamento nativa, com navigator.share e substitutos da área de transferência na web.
SiteToApp.notifications.requestPermission()Solicite permissão de notificação após um gesto do usuário e retorne o status resultante.
SiteToApp.notifications.openSettings()Abra as configurações do sistema operacional deste aplicativo quando a permissão foi negada anteriormente.
SiteToApp.haptics.impact(style)Solicite feedback de impacto leve, médio ou forte. Este é um ambiente autônomo quando não há suporte.
SiteToApp.on(event, handler)Assine um evento de aplicativo validado e receba uma função de cancelamento de assinatura.
SiteToApp.once(event, handler)Inscreva-se para o próximo evento correspondente e remova o manipulador automaticamente.
Erros de digitação: INVALID_ARGUMENT, UNSUPPORTED, NOT_ALLOWED, TIMEOUT, FETCH_FAILED, PROTOCOL_MISMATCH, e NATIVE_ERROR.
Um envelope de mensagem pequeno e confirmado.
A camada JavaScript normaliza os detalhes de transporte da plataforma. No aplicativo, as mensagens viajam pelo transporte React Native WebView como JSON serializado por meio de window.ReactNativeWebView.postMessage. O envelope é independente desse transporte.
Site para aplicativo
{
"channel": "sitetoapp",
"protocolVersion": 1,
"id": "sta_01J8ZQ6JY1",
"type": "navigation.badge.set",
"payload": {
"itemId": "cart",
"value": 3
},
"timestamp": 1789584000000
}Reconhecimento do aplicativo
{
"channel": "sitetoapp",
"protocolVersion": 1,
"type": "response",
"replyTo": "sta_01J8ZQ6JY1",
"ok": true,
"payload": null
}Aplicativo para site
// Native shell → website. Internal SDK method; not public surface.
window.SiteToApp.__receive({
channel: 'sitetoapp',
protocolVersion: 1,
type: 'event',
event: 'app:resume',
payload: { occurredAt: Date.now() },
});- O SDK começa com
bridge.hello; o aplicativo responde com versões e recursos de protocolo suportados. - Cada comando obtém um ID exclusivo. Os comandos que precisam de confirmação recebem uma resposta referenciando esse ID.
- O tempo limite de confirmação padrão é de dois segundos. As respostas tardias são ignoradas depois que o tempo limite é estabelecido.
- As mensagens são apenas JSON, limitadas a 64 KB e analisadas exatamente uma vez em cada lado.
- Mudanças repetidas de títulos e emblemas são rejeitadas; o último valor válido vence.
__receiveé apenas de implementação, não enumerável sempre que possível e rejeita mensagens fora do esquema.
A ponte é estreita por design.
Uma ponte WebView cria autoridade nativa dentro do conteúdo da web, de modo que o shell do aplicativo trata cada mensagem da página como entrada não confiável, mesmo quando a página pertence a você. Ele impõe estas regras:
A ponte é ativada apenas nas origens HTTPS exatas e nos padrões de URL configurados para seu aplicativo e desativada antes de navegar em outro lugar.
Os tipos de mensagens são permitidos e cada carga útil é validada em relação ao esquema de protocolo negociado. Os campos desconhecidos são ignorados e os comandos desconhecidos são rejeitados.
Credenciais de armazenamento, tokens push, identificadores de dispositivos, cookies de autenticação e caminhos de sistemas de arquivos nativos nunca são expostos ao JavaScript da página.
Somente URLs relativos ou destinos HTTPS validados são aceitos. javascript:, data:, file:, intent: e esquemas personalizados são bloqueados, a menos que um comando específico os inclua na lista de permissões.
Solicitações de permissão, compartilhamento de substitutos, links de configurações e ações nativas perturbadoras exigem um gesto recente do usuário.
Os comandos têm taxa limitada, as mensagens são limitadas a 64 KB e as strings e chamadas nativas têm limites de comprimento e tempos limite.
As cargas úteis são editadas dos logs de produção. Os erros de diagnóstico contêm códigos e IDs de mensagens, nunca conteúdo ou segredos do cliente.
As solicitações de selo assistidas seguem as regras de busca do navegador. Credenciais da mesma origem são o padrão; URLs de origem cruzada devem passar pelo CORS.
Teste sua integração.
O SDK altera apenas o comportamento dentro do seu aplicativo. Verifique os dois caminhos para que os usuários do aplicativo tenham a experiência nativa e os visitantes do navegador mantenham o site funcionando exatamente como antes.
- Abra as páginas que chamam o SDK em um navegador móvel normal e confirme que nada quebra quando
context.availableé falso. - Teste no aplicativo em iOS e Android, incluindo redes lentas, estado off-line e retomada após muito tempo em segundo plano.
- Verifique títulos, emblemas e navegação ativa após recargas e alterações de rota do lado do cliente.
- Para ações nativas, teste os caminhos de gesto do usuário, permissão negada e sem suporte.
- Se o seu site usa uma Política de Segurança de Conteúdo, permita a origem do script SDK.
Tem um caso de uso que este contrato perdeu?
Compartilhe o fluxo do site, o comportamento do aplicativo que você precisa e o que deve acontecer em um navegador normal. Isso é suficiente para avaliarmos.