Configurar o comportamento de hospedagem

Com o Firebase Hosting, é possível configurar um comportamento de hospedagem personalizado, incluindo páginas de erro, redirecionamentos, substituições e cabeçalhos personalizados. Também é possível especificar quais arquivos implantar do diretório para o projeto do Firebase.

Defina a configuração do Firebase Hosting no seu arquivofirebase.json.

Encontre seu arquivo firebase.json na raiz do diretório do seu projeto. O Firebase cria automaticamente seu arquivo firebase.json quando o comando firebase init for executado.

É 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

Especificar os arquivos a serem 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 o padrão glob da mesma maneira que o Git manipula .gitignore.

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

"hosting": {
  // ...

  "ignore": [
    "firebase.json",  // the Firebase configuration file (this file)
    "**/.*",  // 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 veicular 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.

Especifique redirecionamentos de URL incluindo um atributo redirects dentro de hosting no seu arquivo firebase.json. Exemplo:

"hosting": {
  // ...

  // Add the "redirects" attribute within "hosting"
  "redirects": [ {
    // Returns a permanent redirect to "/bar" for requests to "/foo" (but not "/foo/**")
    "source": "/foo",
    "destination": "/bar",
    "type": 301
  }, {
    // Returns a permanent redirect to "/bar" for requests to both "/foo" and "/foo/**"
    "source": "/foo{,/**}"
    "destination": "/bar"
    "type": 301
  }, {
    // Returns a temporary redirect for all requests to files or directories in the "firebase" directory
    "source": "/firebase/**",
    "destination": "https://firebase.google.com/",
    "type": 302
  } ]
}

O atributo redirects contém uma matriz de regras de redirecionamento em que cada regra deve incluir:

  • Um source especificando um padrão de glob

  • Um destination, que é um URL estático que pode ser um caminho relativo ou absoluto

  • Um type especificando o código de resposta HTTP

O Firebase Hosting compara o valor source 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 para fazer uma nova solicitação no URL destination.

Por fim, o valor type especifica o código de resposta HTTP específico exibido e pode ser 301 para "Movido permanentemente" ou 302 para "Encontrado" (Redirecionamento temporário).

Capturar segmentos de URL para redirecionamentos

Opcional
Às vezes, pode ser necessário capturar segmentos específicos de um redirecionamento source e reutilizar esses segmentos no URL de redirecionamento destination.

É possível capturar esses segmentos incluindo um prefixo : para identificar o segmento. Caso também precise capturar o caminho de URL restante após o segmento, inclua um * imediatamente após o segmento. Exemplo:

"hosting": {
  // ...

  "redirects": [ {
    "source": "/blog/:post*",  // captures the entire URL segment beginning at "post"
    "destination": "https://blog.myapp.com/:post", // includes the entire URL segment identified and captured by the "source" value
    "type": 301
  }, {
    "source": "/users/:id/profile",  // captures only the URL segment "id", but nothing following
    "destination": "/users/:id/newProfile",  // includes the URL segment identified and caputured by the "source" value
    "type": 301
  } ]
}

Configurar substituições

Opcional
Use uma substituição para mostrar o mesmo conteúdo para vários URLs. As substituições são particularmente úteis 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 dar suporte a apps que usam HTML5 pushState para navegação. Quando um navegador tenta abrir um URL de source especificado, ele recebe o conteúdo do arquivo no URL de destination.

Especifique as substituições de URL ao incluir um atributorewrites dentro do hosting em seu arquivo firebase.json. Exemplo:

"hosting": {
  // ...

  // Add the "rewrites" attribute within "hosting"
  "rewrites": [ {
    // Serves index.html for requests to files or directories that do not exist
    "source": "**",
    "destination": "/index.html"
  }, {
    // Serves index.html for requests to both "/foo" and "/foo/**"
    // Using "/foo/**" only matches paths like "/foo/xyz", but not "/foo"
    "source": "/foo{,/**}",
    "destination": "/index.html"
  }, {
    // Excludes specified pathways from rewrites
    "source": "!/@(js|css)/**",
    "destination": "/index.html"
  } ]
}

O atributo rewrites contém uma matriz de regras de substituição, em que cada regra deve incluir:

  • Um source especificando um padrão de glob

  • Um destination, que é um arquivo local que deve existir

O Firebase Hosting só aplicará uma regra de substituição se um arquivo ou diretório não existir no source especificado. Quando uma regra é acionada, o navegador retorna o conteúdo real do destination especificado em vez de um redirecionamento HTTP.

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": {
  // ...

  // Add the "rewrites" attribute within "hosting"
  "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: projectID.web.app/bigben e projectID.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": {
 // ...

 // Add the "rewrites" attribute within "hosting"
 "rewrites": [ {
   "source": "/helloworld",
   "run": {
     "serviceId": "helloworld",  // "service name" (from when you <a href="#deploy">deployed the container image)</a>
     "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: projectID.web.app/helloworld e projectID.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.

Por exemplo:

  • Use seu domínio 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": "/**",  // Dynamic Links start with "https://<your-domain>/"
        "dynamicLinks": true
      } ]
    }
    
  • Especifique os prefixos de caminho que você quer usar 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/**",  // Dynamic Links can start with "https://<your-domain>/promos/"
        "dynamicLinks": true
      }, {
        "source": "/links/share/**",  // Dynamic Links can start with "https://<your-domain>/links/share/"
        "dynamicLinks": true
      } ]
    }
    

Configurar o Dynamic Links no arquivo firebase.json requer:

  • Um atributo appAssociation definido como AUTO.

    • O padrão para appAssociation é AUTO se você não incluir o atributo na sua configuração.
    • Com esse atributo definido como AUTO, o Hosting gera dinamicamente os arquivos assetlinks.json e apple-app-site-association quando eles são solicitados.
  • Um atributo rewrites para Dynamic Links que contém uma matriz de regras de substituição, em que cada regra deve incluir:

    • Um source especificando um caminho que você quer usar para o Dynamic Links

      • Ao contrário das regras que substituem caminhos por URLs, as regras de substituição do Dynamic Links não podem conter expressões regulares.
    • Um atributo dynamicLinks 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 seu conteúdo, incluindo controle de acesso, autenticação, armazenamento em cache e codificação.

Especifique cabeçalhos de resposta personalizados e específicos para arquivos ao incluir um atributo headers em hosting em seu arquivo firebase.json. Exemplo:

"hosting": {
  // ...

  // Add the "headers" attribute within "hosting"
  "headers": [ {
    // Specifies a CORS header for all font files
    "source": "**/*.@(eot|otf|ttf|ttc|woff|font.css)",
    "headers": [ {
      "key": "Access-Control-Allow-Origin",
      "value": "*"
    } ]
  }, {
    // Overrides the default 1 hour browser cache with a 2 hour cache for all image files
    "source": "**/*.@(jpg|jpeg|gif|png)",
    "headers": [ {
      "key": "Cache-Control",
      "value": "max-age=7200"
    } ]
  }, {
    // Sets the cache header for 404 pages to cache for 5 minutes
    "source": "404.html",
    "headers": [ {
      "key": "Cache-Control",
      "value": "max-age=300"
    } ]
  } ]
}

O atributo headers contém uma matriz de definições em que cada definição deve incluir:

  • Um valor de source que o Hosting corresponde ao caminho da solicitação original, independentemente das regras de substituição.

  • Uma matriz de (sub -) headers que o Hosting aplica ao caminho da solicitação; cada matriz de subcabeçalho precisa incluir uma key e um value especificados.

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.

Especifique a inclusão de extensões .html ao incluir um atributo cleanUrls em hosting em seu arquivo firebase.json. Exemplo:

"hosting": {
  // ...

  // Add the "cleanUrls" attribute within "hosting"
  "cleanUrls": true
}

Controlar barras finais

Opcional
O atributo trailingSlash permite que você controle se os URLs precisam 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).

Especifique a inclusão de barras finais incluindo um atributo trailingSlash em hosting em seu arquivo firebase.json. Exemplo:

"hosting": {
  // ...

  // Add the "trailingSlash" attribute within "hosting"
  "trailingSlash": false
}

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",

  }
}