Configurar o comportamento de hospedagem

Com o Firebase Hosting, é possível configurar o comportamento de hospedagem personalizado para solicitações ao seu site.

O que é possível configurar para o Hosting?

  • Especificar quais arquivos no diretório do seu projeto local você quer implantar no Firebase Hosting. Saiba como.

  • Exibir uma página personalizada com o "erro 404: não encontrada". Saiba como.

  • Configurar redirects para páginas que você moveu ou excluiu. Saiba como.

  • Configurar rewrites para qualquer uma destas finalidades:

    • Mostrar o mesmo conteúdo em vários URLs. Saiba como.

    • Exibir uma função ou acessar um contêiner do Cloud Run usando um URL do Hosting. Saiba como: função ou contêiner.

    • Criar um link dinâmico de domínio personalizado. Saiba como.

  • Adicionar headers para transmitir informações adicionais sobre uma solicitação ou resposta, por exemplo, sobre como os navegadores devem lidar com a página o conteúdo dela (autenticação, armazenamento em cache, codificação etc.). Saiba como.

  • Configurar substituições de internacionalização (i18n) para exibir conteúdo específico com base na preferência de idioma e/ou país de um usuário. Saiba como (página alternativa).

Onde definir a configuração do Hosting?

Faça isso no arquivo firebase.json. O Firebase cria automaticamente o arquivo firebase.json na raiz do diretório do projeto quando você executa o comando firebase init.

É possível encontrar um exemplo de configuração firebase.json completo (abrangendo apenas o Firebase Hosting) na parte inferior desta página. Observe que um arquivo firebase.json também pode conter configurações para outros serviços do Firebase.

É possível verificar o conteúdo firebase.json implementado usando a API REST do Hosting.

Ordem de prioridade das respostas do Hosting

As diferentes opções de configuração do Firebase Hosting descritas nesta página podem, às vezes, se sobrepor. Se houver um conflito, o Hosting determinará sua resposta usando a seguinte ordem de prioridade:

  1. Namespaces reservados que começam com um segmento de caminho /__/*
  2. Redirecionamentos configurados
  3. Conteúdo estático de correspondência exata
  4. Substituições configuradas
  5. Página 404 personalizada
  6. Página 404 padrão

Se você estiver usando substituições i18n, a ordem de prioridade de processamento de correspondência exata e 404 serão expandidas no escopo para acomodar seu "conteúdo de i18n".

Especificar os arquivos que serão implantados

Os atributos padrão public e ignore, incluídos no arquivo firebase.json padrão, definem quais arquivos no diretório do projeto devem ser implantados no projeto do Firebase.

A configuração hosting padrão em um arquivo firebase.json será semelhante ao abaixo:

"hosting": {
  "public": "public",  // the only required attribute for Hosting
  "ignore": [
    "firebase.json",
    "**/.*",
    "**/node_modules/**"
  ]
}

public

Obrigatório
O atributo public especifica qual diretório será implantado no Firebase Hosting. O valor padrão é um diretório chamado public, mas é possível especificar o caminho de qualquer diretório, contanto que ele exista no diretório do seu projeto.

Veja abaixo o nome especificado padrão do diretório a ser implantado:

"hosting": {
  "public": "public"

  // ...
}

É possível alterar o valor padrão para o diretório que você quer implantar:

"hosting": {
  "public": "dist/app"

  // ...
}

ignore

Opcional
O atributo ignore especifica os arquivos a serem ignorados na implantação. Ele pode usar globs da mesma forma que o sistema Git (em inglês) faz com o .gitignore.

Veja abaixo os valores padrão dos arquivos a serem ignorados:

"hosting": {
  // ...

  "ignore": [
    "firebase.json",  // the Firebase configuration file (the file described on this page)
    "**/.*",  // files with a leading period should be hidden from the system
    "**/node_modules/**"  // contains dependencies used to create your site but not run it
  ]
}

Personalizar uma página 404/não encontrada

Opcional
Você pode exibir um erro 404 Not Found personalizado quando um usuário tentar acessar uma página que não existe.

Criar um novo arquivo no diretório public do projeto, nomeie-o como 404.html e adicione o conteúdo 404 Not Found personalizado para o arquivo.

O Firebase Hosting exibirá o conteúdo desse 404.html personalizado se um navegador acionar um erro 404 Not Found no seu domínio ou subdomínio.

Configurar redirecionamentos

Opcional
Use um redirecionamento de URL para evitar links corrompidos se você tiver movido uma página ou para encurtar URLs. Por exemplo, você pode redirecionar um navegador de example.com/team para example.com/about.html.

Se for preciso especificar redirecionamentos de URL, crie um atributo redirects que contenha uma matriz de objetos (chamada de "regras de redirecionamento"). Em cada regra, especifique um padrão de URL que aciona o Hosting para responder com um redirecionamento ao destino especificado em caso de correspondência com o caminho do URL da solicitação.

Esta é a estrutura básica de um atributo redirects. O exemplo a seguir redireciona solicitações para /foo ao fazer uma nova solicitação para /bar.

"hosting": {
  // ...

  // Returns a permanent redirect to "/bar" for requests to "/foo" (but not "/foo/**")
  "redirects": [ {
    "source": "/foo",
    "destination": "/bar",
    "type": 301
  } ]
}

O atributo redirects contém uma matriz de regras de redirecionamento. Nele, cada regra precisa incluir os campos na tabela abaixo.

O Firebase Hosting compara o valor source ou regex com todos os caminhos de URL no início de cada solicitação antes de o navegador determinar se um arquivo ou uma pasta existe nesse caminho. Se uma correspondência for encontrada, o servidor de origem do Firebase Hosting enviará uma resposta de redirecionamento HTTP informando ao navegador que é necessário fazer uma nova solicitação no URL destination.

Campo Descrição
redirects
source (recomendado)
ou regex

Um padrão de URL que, se corresponder ao URL da solicitação inicial, acionará o Hosting para aplicar o redirecionamento

destination

Um URL estático em que o navegador deve fazer uma nova solicitação

Esse URL pode ser um caminho relativo ou absoluto.

type

O código de resposta HTTP

  • Use o tipo 301 para "Movido permanentemente".
  • Use o tipo 302 para "Encontrado" (redirecionamento temporário).

Capturar segmentos de URL para redirecionamentos

Opcional
Às vezes, pode ser necessário capturar segmentos específicos do padrão de URL de uma regra de redirecionamento (valor source ou regex) e depois reutilizá-los no caminho destination da regra.

Configurar substituições

Opcional
Use uma substituição para mostrar o mesmo conteúdo para vários URLs. Essa função é particularmente útil com a correspondência de padrões, já que é possível aceitar qualquer URL que corresponda ao padrão e deixar que o código do cliente decida o que exibir.

As substituições também podem ser usadas para oferecer compatibilidade com apps que usam HTML5 pushState (em inglês) para navegação. Quando um navegador tenta abrir um caminho de URL que corresponde ao padrão de URL source ou regex especificado, o navegador recebe o conteúdo do arquivo no URL destination.

Para especificar substituições de URL, crie um atributo rewrites que contenha uma matriz de objetos (chamada de "regras de substituição"). Em cada regra, especifique um padrão de URL que, em caso de correspondência com o caminho do URL da solicitação, aciona o Hosting para responder como se o serviço tivesse recebido o URL de destino especificado.

Esta é a estrutura básica de um atributo rewrites. O exemplo a seguir exibe index.html para solicitações a arquivos ou diretórios que não existem.

"hosting": {
  // ...

  // Serves index.html for requests to files or directories that do not exist
  "rewrites": [ {
    "source": "**",
    "destination": "/index.html"
  } ]
}

O atributo rewrites contém uma matriz de regras de substituição, em que cada regra precisa incluir os campos na tabela abaixo.

O Firebase Hosting só aplicará uma regra de substituição se um arquivo ou diretório não existir em um caminho de URL que corresponda ao padrão de URL source ou regex especificado. Quando uma solicitação aciona uma regra de substituição, o navegador retorna o conteúdo real do arquivo destination especificado, em vez de um redirecionamento HTTP.

Campo Descrição
rewrites
source (recomendado)
ou regex

Um padrão de URL que, se corresponder ao URL da solicitação inicial, acionará o Hosting para aplicar a substituição

destination

Um arquivo local que precisa existir

Esse URL pode ser um caminho relativo ou absoluto.

Solicitações diretas para uma função

É possível usar rewrites para exibir uma função de um URL do Firebase Hosting. O exemplo a seguir é um trecho da exibição de conteúdo dinâmico usando o Cloud Functions.

Por exemplo, caso queira direcionar todas as solicitações da página /bigben no site do Hosting para executar a função bigben:

"hosting": {
  // ...

  // Directs all requests from the page `/bigben` to execute the `bigben` function
  "rewrites": [ {
    "source": "/bigben",
    "function": "bigben"
  } ]
}

Depois de adicionar esta regra de substituição e implantar no Firebase (usando firebase deploy), a função pode ser acessada pelos seguintes URLs:

  • Subdomínios do Firebase:
    PROJECT_ID.web.app/bigben e PROJECT_ID.firebaseapp.com/bigben

  • Qualquer domínio personalizado conectado:
    CUSTOM_DOMAIN/bigben

Solicitações diretas para um contêiner do Cloud Run

É possível usar rewrites para acessar um contêiner do Cloud Run a partir de um URL do Firebase Hosting. O exemplo a seguir é um trecho da exibição de conteúdo dinâmico usando o Cloud Run.

Por exemplo, para direcionar todas as solicitações da página /helloworld no site do Hosting para acionar a inicialização e execução de um instância de contêiner helloworld:

"hosting": {
 // ...

 // Directs all requests from the page `/helloworld` to trigger and run a `helloworld` container
 "rewrites": [ {
   "source": "/helloworld",
   "run": {
     "serviceId": "helloworld",  // "service name" (from when you deployed the container image)
     "region": "us-central1"  // optional (if omitted, default is us-central1)
   }
 } ]
}

Depois de adicionar esta regra de substituição e implantar no Firebase (usando firebase deploy), sua imagem de contêiner pode ser acessada pelos seguintes URLs:

  • Subdomínios do Firebase:
    PROJECT_ID.web.app/helloworld e PROJECT_ID.firebaseapp.com/helloworld

  • Qualquer domínio personalizado conectado:
    CUSTOM_DOMAIN/helloworld

É possível usar rewrites para criar Dynamic Links de domínio personalizado. Acesse a documentação do Dynamic Links para receber informações detalhadas sobre a configuração de um domínio personalizado para Dynamic Links.

  • Use seu domínio personalizado apenas para Dynamic Links:

    "hosting": {
      // ...
    
      "appAssociation": "AUTO",  // required for Dynamic Links (default is AUTO if not specified)
    
      // Add the "rewrites" attribute within "hosting"
      "rewrites": [ {
        "source": "/**",  // the Dynamic Links start with "https://CUSTOM_DOMAIN/"
        "dynamicLinks": true
      } ]
    }
    
  • Especifique os prefixos de caminho do domínio personalizado que serão usados para Dynamic Links:

    "hosting": {
      // ...
    
      "appAssociation": "AUTO",  // required for Dynamic Links (default is AUTO if not specified)
    
      // Add the "rewrites" attribute within "hosting"
      "rewrites": [ {
        "source": "/promos/**",  // the Dynamic Links start with "https://CUSTOM_DOMAIN/promos/"
        "dynamicLinks": true
      }, {
        "source": "/links/share/**",  // the Dynamic Links start with "https://CUSTOM_DOMAIN/links/share/"
        "dynamicLinks": true
      } ]
    }
    

Veja a seguir os requisitos para a configuração do Dynamic Links no arquivo firebase.json:

Campo Descrição
appAssociation

Precisa ser definido como AUTO

  • Se você não incluir esse atributo na sua configuração, o padrão para appAssociation será AUTO.
  • Ao definir esse atributo como AUTO, o Hosting poderá gerar dinamicamente arquivos assetlinks.json e apple-app-site-association quando eles forem solicitados.
rewrites
source

Um caminho que você quer usar para Dynamic Links

Ao contrário das regras que substituem caminhos para URLs, as regras de substituição de Dynamic Links não podem conter expressões regulares.

dynamicLinks Precisa ser definido como true

Configurar cabeçalhos

Opcional
Os cabeçalhos permitem que o cliente e o servidor passem informações adicionais junto com uma solicitação ou uma resposta. Alguns conjuntos de cabeçalhos podem afetar como o navegador lida com a página e o conteúdo dela, incluindo controle de acesso, autenticação, armazenamento em cache e codificação.

Crie um atributo headers que contenha uma matriz de objetos de cabeçalho para especificar cabeçalhos de resposta personalizados e específicos do arquivo. Em cada objeto, especifique um padrão de URL que aciona o Hosting para aplicar os cabeçalhos de resposta personalizados especificados em caso de correspondência com o caminho do URL da solicitação.

Esta é a estrutura básica de um atributo headers. O exemplo a seguir aplica um cabeçalho CORS para todos os arquivos de fonte.

"hosting": {
  // ...

  // Applies a CORS header for all font files
  "headers": [ {
    "source": "**/*.@(eot|otf|ttf|ttc|woff|font.css)",
    "headers": [ {
      "key": "Access-Control-Allow-Origin",
      "value": "*"
    } ]
  } ]
}

O atributo headers contém uma matriz de definições, em que cada definição precisa incluir os campos na tabela abaixo.

Campo Descrição
headers
source (recomendado)
ou regex

Um padrão de URL que, se corresponder ao URL da solicitação inicial, acionará o Hosting para aplicar o cabeçalho personalizado

Para criar um cabeçalho que será usado na sua página personalizada com erro 404, utilize 404.html como seu valor source ou regex.

matriz de (sub-)headers

Os cabeçalhos personalizados que o Hosting aplica ao caminho da solicitação

Cada sub-cabeçalho precisa incluir uma key e um value (veja as próximas duas linhas).

key O nome do cabeçalho, por exemplo, Cache-Control
value O valor do cabeçalho, por exemplo, max-age=7200

Saiba mais sobre Cache-Control na seção de Hosting que descreve a exibição de conteúdo dinâmico e hospedagem de microsserviços. Também é possível saber mais sobre os cabeçalhos CORS.

Controlar extensões .html

Opcional
O atributo cleanUrls permite que você controle se os URLs devem ou não incluir a extensão .html.

Quando true, o Hosting descarta automaticamente a extensão .html dos URLs de arquivos enviados. Se uma extensão .html for adicionada na solicitação, o Hosting executará um redirecionamento 301 para o mesmo caminho, mas eliminará a extensão .html.

Veja como controlar a inclusão de .html nos URLs com a adição de um atributo cleanUrls:

"hosting": {
  // ...

  // Drops `.html` from uploaded URLs
  "cleanUrls": true
}

Controlar barras finais

Opcional
O atributo trailingSlash permite controlar se os URLs de conteúdo estático devem incluir barras finais.

  • Quando true, o Hosting redireciona URLs para adicionar uma barra final.
  • Quando false, o Hosting redireciona URLs para remover uma barra final.
  • Quando não especificado, o Hosting usa barras finais somente para arquivos de índice de diretório (por exemplo, about/index.html).

Veja como controlar as barras finais com a adição de um atributo trailingSlash:

"hosting": {
  // ...

  // Removes trailing slashes from URLs
  "trailingSlash": false
}

O atributo trailingSlash não afeta as substituições em conteúdo dinâmico exibido pelo Cloud Functions ou Cloud Run.

Correspondência de padrões glob

As opções de configuração do Firebase Hosting fazem uso extensivo da notação de correspondência de padrão glob com extglob, semelhante a como o Git manipula as regras gitignore e o Bower manipula as regras ignore. Esta página da wiki é uma referência mais detalhada, mas as seguintes são explicações dos exemplos usados nesta página:

  • firebase.json: corresponde apenas ao arquivo firebase.json na raiz do diretório public

  • **: corresponde a qualquer arquivo ou pasta em um subdiretório arbitrário

  • * corresponde apenas a arquivos e pastas na raiz do diretório public

  • **/.*: corresponde a qualquer arquivo iniciado por . (geralmente arquivos ocultos, como na pasta .git) em um subdiretório arbitrário

  • **/node_modules/**: corresponde a qualquer arquivo ou pasta em um subdiretório arbitrário de uma pasta node_modules, que pode estar em um subdiretório arbitrário do diretório public

  • **/*.@(jpg|jpeg|gif|png): corresponde a qualquer arquivo em um subdiretório arbitrário que termine com exatamente uma das seguintes opções: .jpg, .jpeg, .gif ou .png

Exemplo de configuração completa do Hosting

Veja a seguir um exemplo de configuração completo de firebase.json para o Firebase Hosting. Observe que um arquivo firebase.json também pode conter configurações para outros serviços do Firebase.

{
  "hosting": {

    "public": "dist/app",  // "public" is the only required attribute for Hosting

    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],

    "redirects": [ {
      "source": "/foo",
      "destination": "/bar",
      "type": 301
    }, {
      "source": "/firebase/**",
      "destination": "https://www.firebase.com",
      "type": 302
    } ],

    "rewrites": [ {
      // Shows the same content for multiple URLs
      "source": "/app/**",
      "destination": "/app/index.html"
    }, {
      // Configures a custom domain for Dynamic Links
      "source": "/promos/**",
      "dynamicLinks": true
    }, {
      // Directs a request to Cloud Functions
      "source": "/bigben",
      "function": "bigben"
    }, {
      // Directs a request to a Cloud Run containerized app
      "source": "/helloworld",
      "run": {
        "serviceId": "helloworld",
        "region": "us-central1"
      }
    } ],

    "headers": [ {
      "source": "**/*.@(eot|otf|ttf|ttc|woff|font.css)",
      "headers": [ {
        "key": "Access-Control-Allow-Origin",
        "value": "*"
      } ]
    }, {
      "source": "**/*.@(jpg|jpeg|gif|png)",
      "headers": [ {
        "key": "Cache-Control",
        "value": "max-age=7200"
      } ]
    }, {
      "source": "404.html",
      "headers": [ {
        "key": "Cache-Control",
        "value": "max-age=300"
      } ]
    } ],

    "cleanUrls": true,

    "trailingSlash": false

    // Required to configure custom domains for Dynamic Links
    "appAssociation": "AUTO",

  }
}