Pular para o conteúdo principal

Sideloading Apps

Sideloading permite instalar mini-programas fora do registro oficial da App Store. Este é o fluxo de trabalho principal durante o desenvolvimento e também como usuários instalam apps compartilhados diretamente por desenvolvedores.

Existem três métodos de sideloading:

MétodoEntradaMelhor Para
URL InstallURL do manifestApps hospedados, desenvolvimento com servidor local
HTML UploadArquivo .html únicoPrototipagem rápida, apps de arquivo único
.ais BundleArquivo ZIP (extensão .ais)Apps multi-arquivo, distribuição offline

Todos os três métodos estão disponíveis na seção Sideload do painel Apps.


URL Install

A maneira padrão de instalar um mini-programa de uma fonte hospedada.

Como Funciona

  1. Você fornece uma URL apontando para um arquivo manifest.json
  2. A plataforma busca e valida o manifest
  3. O arquivo HTML de entrada é buscado de {base_url}{entry}
  4. Um diálogo de permissão mostra o nome do app, descrição e permissões solicitadas
  5. Com aprovação, o manifest e HTML cacheado são armazenados em IndexedDB
  6. O app aparece no grid de apps instalados

Passos

  1. Abra o painel Apps (clique no ícone de apps na barra lateral esquerda)
  2. Role até a seção Sideload
  3. Cole a URL do manifest no campo de texto:
    https://example.com/my-app/manifest.json
  4. Clique Install
  5. Revise as permissões e clique Allow

Desenvolvimento com Localhost

Durante o desenvolvimento, sirva seu app localmente e instale de localhost:

cd my-app
python3 -m http.server 8080

Então instale de: http://localhost:8080/manifest.json

dica

A maioria dos servidores HTTP locais serve arquivos com headers CORS permissivos por padrão. Se você receber erros "Failed to fetch manifest", certifique-se de que seu servidor inclui Access-Control-Allow-Origin: * em suas respostas.

Atualizando um App Sideloaded

A plataforma cacheia o HTML de entrada no momento da instalação. Para pegar mudanças de código:

  1. Desinstale o app (clique no botão X no card do app)
  2. Reinstale da mesma URL

Não há mecanismo de atualização automática para apps sideloaded. Apps do registro verificam por atualizações usando comparação de versão durante o ciclo de refresh do registro.


HTML Upload

A maneira mais rápida de testar um mini-programa. Faça upload de um único arquivo HTML e a plataforma cria um manifest sintético automaticamente.

Como Funciona

  1. Você seleciona um arquivo .html ou .htm do seu computador
  2. A plataforma lê o conteúdo do arquivo (máx 5 MB)
  3. Um manifest sintético é gerado:
    • name: derivado do nome do arquivo (minúsculas, hífens, máx 64 chars)
    • version: 1.0.0
    • entry: index.html
    • base_url: local://
    • permissions: ["storage"] (mínimo)
    • description: "Sideloaded from {filename}"
  4. Um diálogo de permissão é mostrado
  5. O HTML é cacheado como conteúdo de entrada

Passos

  1. Abra o painel Apps
  2. Na seção Sideload, clique Upload App
  3. Selecione seu arquivo .html
  4. Revise as permissões e clique Allow

Limitações

  • Apenas arquivo único -- CSS, JS e imagens externas referenciados por URLs relativos não carregarão porque o iframe tem origem nula e base_url é definido como local://
  • Permissões mínimas -- O manifest sintético concede apenas storage. Se seu app precisa de chat:read ou outras permissões, use URL Install ou um bundle .ais em vez disso
  • 5 MB máx -- Arquivos maiores que 5 MB são rejeitados
  • Sem customização de manifest -- Você não pode definir descrição, ícone ou permissões customizadas
informação

HTML Upload é projetado para prototipagem rápida. Para apps que precisam de múltiplos arquivos ou permissões específicas, use um bundle .ais ou URL Install.

Fazendo Apps de Arquivo Único Funcionarem

Para aproveitar ao máximo o HTML Upload, mantenha tudo inline no seu HTML:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style>
/* Inlines todo CSS aqui */
body {
font-family: system-ui;
padding: 16px;
color: #e0e0e0;
background: #1a1a2e;
}
</style>
</head>
<body>
<h1>Meu App</h1>
<script>
// Inlines todo JavaScript aqui
ais.ready(function () {
ais.ui.toast("App carregado!");
});
</script>
</body>
</html>

Imagens podem ser embutidas como data URIs:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..." />

.ais Bundle

Um bundle .ais é um arquivo ZIP padrão com extensão de arquivo .ais. Contém o manifest, HTML de entrada e todos os assets. A plataforma extrai o ZIP e inlines todos os assets referenciados em um único documento HTML no momento da instalação.

Como Funciona

  1. Você faz upload de um arquivo .ais (máx 50 MB)
  2. A plataforma parseia o ZIP usando DecompressionStream nativo
  3. manifest.json é extraído e validado da raiz do ZIP
  4. O arquivo HTML de entrada (referenciado por entry no manifest) é extraído
  5. Todos os outros arquivos no ZIP estão disponíveis como assets para inlining
  6. Inlining de assets transforma o HTML:
    • <link rel="stylesheet" href="style.css"> se torna <style>{conteúdo CSS}</style>
    • <script src="app.js"></script> se torna <script>{conteúdo JS}</script>
    • <img src="icon.png"> se torna <img src="data:image/png;base64,{base64}">
    • url(bg.png) em estilos inline se torna url(data:image/png;base64,...)
  7. O diálogo de permissão mostra as permissões do manifest
  8. O HTML inlineado é cacheado em IndexedDB

Estrutura do Bundle

my-app.ais (arquivo ZIP)
|-- manifest.json (obrigatório, na raiz)
|-- index.html (obrigatório, referenciado por manifest "entry")
|-- style.css (opcional, inlineado em <style>)
|-- app.js (opcional, inlineado em <script>)
|-- icon.png (opcional, inlineado como data URI)
|-- images/
| |-- logo.svg (opcional, inlineado como data URI)
|-- fonts/
|-- custom.woff2 (opcional, inlineado como data URI)

Criando um Bundle

# Navegue para o diretório do seu app
cd my-app

# Verifique seus arquivos
ls
# manifest.json index.html style.css app.js icon.png

# Crie o bundle
zip -r ../my-app.ais manifest.json index.html style.css app.js icon.png

Ou faça zip de todo o diretório:

cd my-app
zip -r ../my-app.ais .
cuidado

O manifest.json deve estar na raiz do ZIP, não dentro de um subdiretório. Se seu ZIP tem uma estrutura como my-app/manifest.json, a plataforma não o encontrará.

O Que É Inlineado

O inliner de assets processa o HTML de entrada e substitui referências relativas com conteúdo inline:

PadrãoSubstituição
<link rel="stylesheet" href="X"><style>{conteúdo de X}</style>
<script src="X"></script><script>{conteúdo de X}</script>
<img src="X"><img src="data:{mime};base64,{data}">
<audio src="X"><audio src="data:{mime};base64,{data}">
<video src="X"><video src="data:{mime};base64,{data}">
<source src="X"><source src="data:{mime};base64,{data}">
url(X) em estilos inlineurl(data:{mime};base64,{data})

Referências que começam com data:, http://, https:// ou // são deixadas inalteradas -- apenas caminhos relativos são inlineados.

Tipos MIME Suportados

A plataforma detecta tipos MIME de extensões de arquivo:

ExtensãoTipo MIME
.csstext/css
.js, .mjstext/javascript
.jsonapplication/json
.pngimage/png
.jpg, .jpegimage/jpeg
.gifimage/gif
.svgimage/svg+xml
.webpimage/webp
.icoimage/x-icon
.wofffont/woff
.woff2font/woff2
.ttffont/ttf
.mp3audio/mpeg
.mp4video/mp4
.webmvideo/webm
.oggaudio/ogg
.wavaudio/wav

Exemplo: Bundle de App Multi-Arquivo

manifest.json:

{
"name": "dashboard",
"version": "1.0.0",
"abi": 1,
"type": "mini-program",
"title": "Dashboard",
"description": "Dashboard de analytics de chat",
"entry": "index.html",
"base_url": "local://",
"permissions": ["storage", "chat:read", "auth:read", "ui:toast"]
}

index.html:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<h1>Dashboard</h1>
<img src="logo.svg" alt="Logo" width="64" />
<div id="stats"></div>
<script src="app.js"></script>
</body>
</html>

style.css:

body {
font-family: system-ui;
padding: 16px;
color: #e0e0e0;
background: #1a1a2e;
}
h1 {
font-size: 22px;
}
#stats {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 12px;
}

app.js:

ais.ready(async function () {
var history = await ais.chat.getHistory(100);
document.getElementById("stats").textContent = history.length + " mensagens";
});

Após instalação do bundle, a plataforma produz um único HTML inlineado:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style>
body {
font-family: system-ui;
padding: 16px;
color: #e0e0e0;
background: #1a1a2e;
}
h1 {
font-size: 22px;
}
#stats {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 12px;
}
</style>
</head>
<body>
<h1>Dashboard</h1>
<img src="data:image/svg+xml;base64,..." alt="Logo" width="64" />
<div id="stats"></div>
<script>
ais.ready(async function () {
var history = await ais.chat.getHistory(100);
document.getElementById("stats").textContent =
history.length + " mensagens";
});
</script>
</body>
</html>

Limites de Tamanho de Arquivo

MétodoTamanho Máx
HTML Upload5 MB
.ais Bundle50 MB
URL InstallSem limite rígido (limitado pela memória do navegador)
aviso

Bundles grandes com muitas imagens embutidas ou arquivos de mídia podem resultar em uma string HTML cacheada muito grande em IndexedDB. Mantenha bundles enxutos -- comprima imagens antes de incluí-las e considere usar URLs externos para assets grandes de mídia.


Segurança

Apps sideloaded obtêm o exato mesmo sandbox que apps do registro:

  • sandbox="allow-scripts allow-forms" (origem nula)
  • Sem acesso ao DOM pai, localStorage ou cookies
  • Comunicação exclusivamente através da bridge postMessage window.ais
  • Permissões impostas pela plataforma host (não pelo iframe)

A única diferença de apps do registro é a ausência de um badge de confiança (Community, AI Verified ou Verified) no grid de apps. Apps sideloaded não têm badge.

informação

Sideloading é o nível "Direct Install" do modelo de distribuição do marketplace. É o mecanismo de distribuição nativo da web -- instale qualquer app de qualquer URL, com o sandbox fornecendo segurança básica.


A UI de Sideload

A seção Sideload no painel Apps fornece:

  1. Campo de entrada de URL -- Cole uma URL de manifest e clique Install
  2. Divisor "or"
  3. Botão Upload App -- Abre um seletor de arquivo aceitando arquivos .html, .htm, .ais e .zip
  4. Texto de ajuda -- "Accepts .html single-file apps or .ais bundles (ZIP with manifest.json)"

Todos os três métodos disparam o diálogo de permissão padrão antes de completar a instalação. Apps instalados aparecem na seção Installed acima, com botões Open e Uninstall.