Configura el comportamiento del Hosting

Firebase Hosting te permite configurar comportamientos de hosting personalizados para las solicitudes que se realizan a tu sitio.

¿Qué puedo configurar en Hosting?

  • Especifica qué archivos del directorio del proyecto local quieres implementar en Firebase Hosting. Descubre cómo hacerlo.

  • Publica una página 404/Not Found personalizada. Descubre cómo hacerlo.

  • Configura redirects para las páginas que moviste o borraste. Descubre cómo hacerlo.

  • Configura rewrites para cualquiera de los siguientes propósitos:

  • Agrega headers para pasar información adicional sobre una solicitud o una respuesta, p. ej., la manera en que los navegadores deben manejar la página y su contenido, como autenticación, almacenamiento en caché, codificación, etcétera. Descubre cómo hacerlo.

  • Configura las reescrituras de internacionalización (i18n) para entregar contenido específico según la preferencia de idioma o el país del usuario. Descubre cómo hacerlo (en otra página).

¿Dónde puedo definir la configuración de Hosting?

Puedes definir la configuración de Firebase Hosting en el archivo firebase.json. Firebase crea tu archivo firebase.json de forma automática en la raíz del directorio del proyecto cuando ejecutas el comando firebase init.

Al final de esta página, se presenta un ejemplo de configuración completo de firebase.json (solo abarca Firebase Hosting). Ten en cuenta que un archivo firebase.json también puede contener configuraciones de otros servicios de Firebase.

Puedes verificar el contenido implementado de firebase.json con la API de REST de Hosting.

Orden de prioridad de las respuestas de Hosting

En ocasiones, las diversas opciones de configuración de Firebase Hosting que se describen en esta página se pueden sobreponer. Si hay un conflicto, Hosting determina su respuesta en este orden de prioridad:

  1. Espacios de nombres reservados que comienzan con un segmento de ruta de acceso /__/*
  2. Redireccionamientos configurados
  3. Contenido estático de coincidencia exacta
  4. Reescrituras configuradas
  5. Página 404 personalizada
  6. Página 404 predeterminada

Si usas reescrituras para i18n, el orden de la prioridad de la coincidencia exacta y del manejo de los errores 404 se amplía en el alcance para adaptarse a tu “contenido de i18n”.

Especifica qué archivos se deben implementar

Los atributos predeterminados public y ignore, que se incluyen en el archivo firebase.json predeterminado, definen qué archivos del directorio del proyecto se deben implementar en el proyecto de Firebase.

La configuración predeterminada de hosting del archivo firebase.json tiene este aspecto:

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

public

Obligatorio
El atributo public especifica qué directorio se debe implementar en Firebase Hosting. El valor predeterminado es un directorio llamado public, pero puedes especificar la ruta de acceso de cualquier directorio, siempre que exista en el directorio del proyecto.

Este es el nombre especificado predeterminado del directorio que se debe implementar:

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

  // ...
}

Puedes cambiar el valor predeterminado por el del directorio que quieres implementar:

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

  // ...
}

ignore

Opcional
El atributo ignore especifica qué archivos se deben ignorar en la implementación. Puede usar los globs de la misma manera que Git controla .gitignore.

Estos son los valores predeterminados de los archivos que se deben pasar por alto:

"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
  ]
}

Personaliza una página 404/“Not Found”

Opcional
Puedes especificar que se muestre un error 404 Not Found personalizado cuando un usuario trate de acceder a una página inexistente.

Crea un archivo nuevo en el directorio public del proyecto, denomínalo 404.html y agrega el contenido personalizado de 404 Not Found al archivo.

Firebase Hosting mostrará el contenido de esta página 404.html personalizada si un navegador activa un error 404 Not Found en el dominio o subdominio.

Configura redireccionamientos

Opcional
Usa el redireccionamiento de URL a fin de evitar la presencia de vínculos rotos si transferiste una página, o bien para acortar URL. Por ejemplo, puedes redireccionar a un navegador de example.com/team a example.com/about.html.

Especifica los redireccionamientos de la URL creando un atributo redirects que contenga un array de objetos denominado “reglas de redireccionamiento”. En cada regla debes especificar un patrón de URL que active Hosting para que redireccione a la URL de destino especificada (si coincide con la ruta de URL de la solicitud).

Esta es la estructura básica de un atributo redirects. En este ejemplo se redireccionan las solicitudes a /foo mediante una nueva solicitud a /bar.

"hosting": {
  // ...

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

El atributo redirects contiene un array de reglas de redireccionamiento en el que cada regla debe incluir los campos que se indican en la siguiente tabla.

Firebase Hosting compara los valores source o regex con todas las rutas de URL al inicio de cada solicitud (antes de que el navegador determine si existe un archivo o una carpeta en esa ruta). Si se encuentra una coincidencia, el servidor de origen de Firebase Hosting enviará una respuesta de redireccionamiento HTTPS para indicarle al navegador que debe realizar una solicitud nueva en la URL destination.

Campo Descripción
redirects
source (recomendado)
o regex

Un patrón de URL que, si coincide con la URL de solicitud inicial, activa Hosting para aplicar el redireccionamiento

destination

Una URL estática en la que el navegador debe realizar una solicitud nueva

Esta URL puede ser una ruta absoluta o relativa.

type

El código de respuesta HTTPS

  • Usa un tipo de 301 para “Transferido permanentemente”.
  • Usa un tipo de 302 para “Encontrado” (redireccionamiento temporal).

Captura segmentos de URL para los redireccionamientos

Opcional
A veces es posible que debas capturar segmentos específicos del patrón de URL de una regla de redireccionamiento (valor source o regex) y, luego, volver a utilizarlos en la ruta destination de la regla.

Configura reescrituras

Opcional
Usa una reescritura para mostrar el mismo contenido en varias URL. Las reescrituras son especialmente útiles con la coincidencia de patrones, ya que puedes aceptar cualquier URL que coincida con el patrón y permitir que el código del cliente decida qué mostrar.

Las reescrituras también sirven para admitir apps que usan HTML5 pushState en la navegación. Cuando un navegador intente abrir una ruta de URL que coincida con el patrón de URL source o regex específico, el navegador le proporcionará el contenido del archivo en la URL destination.

Crea un atributo rewrites que contenga un array de objetos denominado “reglas de reescritura” para especificar las reescrituras de URL. Especifica en cada regla un patrón de URL que active Hosting para que responda como si se le otorgara al servicio la URL de destino especificada (si coincide con la ruta de URL de la solicitud).

Esta es la estructura básica de un atributo rewrites. En este ejemplo se entrega index.html para solicitudes a archivos o directorios que no existen.

"hosting": {
  // ...

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

El atributo rewrites contiene un array de reglas de reescritura en el que cada regla debe incluir los campos que se indican en la tabla a continuación.

Firebase Hosting solo aplicará una regla de reescritura si un archivo o directorio no existe en la ruta de URL que coincide con el patrón de URL source o regex especificado. Cuando una solicitud activa una regla de reescritura, el navegador muestra el contenido real del archivo destination especificado en lugar de un redireccionamiento HTTP.

Campo Descripción
rewrites
source (recomendado)
o regex

Un patrón de URL que, si coincide con la URL de solicitud inicial, activa Hosting para aplicar la reescritura.

destination

Un archivo local que debe existir

Esta URL puede ser una ruta absoluta o relativa.

Dirige las solicitudes a una función

Puedes usar rewrites para entregar funciones desde una URL de Firebase Hosting. El siguiente ejemplo es un extracto del artículo sobre cómo entregar contenido dinámico con Cloud Functions.

Por ejemplo, para indicar que todas las solicitudes de la página /bigben del sitio de Hosting ejecuten la función bigben, haz lo siguiente:

"hosting": {
  // ...

  // Directs all requests from the page `/bigben` to execute the `bigben` function
  "rewrites": [ {
    "source": "/bigben",
    "function": {
      "functionId": "bigben",
      "region": "us-central1"  // optional (see note below)
      "pinTag": true           // optional (see note below)
    }
  } ]
}

Después de agregar esta regla de reescritura y de implementarla en Firebase (con firebase deploy), puedes acceder a la función a través de las siguientes URLs:

  • Tus subdominios de Firebase:
    PROJECT_ID.web.app/bigben y PROJECT_ID.firebaseapp.com/bigben

  • Cualquier dominio personalizado conectado:
    CUSTOM_DOMAIN/bigben

Cuando se redireccionan solicitudes a funciones con Hosting, los métodos de solicitud HTTP admitidos son GET, POST, HEAD, PUT, DELETE, PATCH y OPTIONS. No se admiten otros métodos, como REPORT o PROFIND.

Dirige las solicitudes a un contenedor de Cloud Run

Puedes usar rewrites para acceder a un contenedor de Cloud Run desde una URL de Firebase Hosting. El siguiente ejemplo es un extracto del artículo sobre cómo entregar contenido dinámico con Cloud Run.

Por ejemplo, para indicar que todas las solicitudes de la página /helloworld del sitio de Hosting activen el inicio y la ejecución de una instancia de contenedor llamada helloworld, haz lo siguiente:

"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)
   }
 } ]
}

Después de agregar esta regla de reescritura y de implementarla en Firebase (con firebase deploy), puedes acceder a la imagen de contenedor a través de las siguientes URLs:

  • Tus subdominios de Firebase:
    PROJECT_ID.web.app/helloworld y PROJECT_ID.firebaseapp.com/helloworld

  • Cualquier dominio personalizado conectado:
    CUSTOM_DOMAIN/helloworld

Cuando se redireccionan solicitudes a contenedores de Cloud Run con Hosting, los métodos de solicitud HTTP admitidos son GET, POST, HEAD, PUT, DELETE, PATCH y OPTIONS. No se admiten otros métodos, como REPORT o PROFIND.

Para obtener el mejor rendimiento, coloca tu servicio de Cloud Run con Hosting por medio de las siguientes regiones:

  • us-west1
  • us-central1
  • us-east1
  • europe-west1
  • asia-east1

Las reescrituras en Cloud Run desde Hosting se admiten en las siguientes regiones:

  • asia-east1
  • asia-east2
  • asia-northeast1
  • asia-northeast2
  • asia-northeast3
  • asia-south1
  • asia-south2
  • asia-southeast1
  • asia-southeast2
  • australia-southeast1
  • australia-southeast2
  • europe-central2
  • europe-north1
  • europe-southwest1
  • europe-west1
  • europe-west12
  • europe-west2
  • europe-west3
  • europe-west4
  • europe-west6
  • europe-west8
  • europe-west9
  • me-central1
  • me-west1
  • northamerica-northeast1
  • northamerica-northeast2
  • southamerica-east1
  • southamerica-west1
  • us-central1
  • us-east1
  • us-east4
  • us-east5
  • us-south1
  • us-west1
  • us-west2
  • us-west3
  • us-west4
  • us-west1
  • us-central1
  • us-east1
  • europe-west1
  • asia-east1

Puedes usar rewrites para crear Dynamic Links de dominios personalizados. Consulta la documentación de Dynamic Links a fin de obtener información detallada sobre cómo configurar un dominio personalizado para Dynamic Links.

  • Usa tu dominio personalizado solo 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
      } ]
    }
    
  • Especifica prefijos de ruta de dominio personalizado para usar en 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
      } ]
    }
    

Para configurar Dynamic Links en el archivo firebase.json, necesitas lo siguiente:

Campo Descripción
appAssociation

Se debe configurar en AUTO

  • Si no incluyes este atributo en tu configuración, el valor predeterminado para appAssociation será AUTO.
  • Si configuras este atributo como AUTO, Hosting puede generar archivos assetlinks.json y apple-app-site-association de forma dinámica cuando se soliciten.
rewrites
source

Una ruta de acceso que quieres usar en Dynamic Links

A diferencia de las reglas que reescriben las rutas de acceso hacia las URL, las reglas de reescritura de Dynamic Links no pueden incluir expresiones regulares.

dynamicLinks Se debe configurar como true

Configura encabezados

Opcional
Los encabezados permiten que tanto el cliente como el servidor pasen información adicional junto con una solicitud o respuesta. Algunos conjuntos de encabezados pueden afectar la manera en que el navegador controla la página y su contenido, incluido el control de acceso, la autenticación, el almacenamiento en caché y la codificación.

Crea un atributo headers que contenga un array de objetos de encabezado para especificar encabezados de respuesta personalizados y específicos de un archivo. En cada objeto especifica un patrón de URL que active Hosting para aplicar los encabezados de respuesta personalizados que se especificaron (si coincide con la ruta de URL de la solicitud).

Esta es la estructura básica de un atributo headers. En este ejemplo se aplica un encabezado de CORS para todos los archivos de fuentes.

"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": "*"
    } ]
  } ]
}

El atributo headers contiene un array de definiciones en el que cada definición debe incluir los campos que se indican en la siguiente tabla.

Campo Descripción
headers
source (recomendado)
o regex

Un patrón de URL que, si coincide con la URL de la solicitud inicial, activa Hosting para aplicar el encabezado personalizado

Para crear un encabezado que coincida con tu página 404 personalizada, usa 404.html como valor de source o regex.

array de (sub)headers

Los encabezados personalizados que Hosting aplica en la ruta de la solicitud

Cada subencabezado debe incluir un par de key y value (consulta las dos filas siguientes).

key El nombre del encabezado, por ejemplo Cache-Control
value El valor del encabezado, por ejemplo max-age=7200

Puedes obtener más información sobre Cache-Control en la sección de Hosting en la que se describen la entrega de contenido dinámico y el hosting de microservicios. También puedes obtener más información sobre los encabezados de CORS.

Controla las extensiones .html

Opcional
El atributo cleanUrls te permite controlar la inclusión de la extensión .html en las URL.

Si se configura como true, Hosting omite automáticamente la extensión .html de las URL de los archivos cargados. Si se agrega una extensión .html a la solicitud, Hosting realiza un redireccionamiento 301 hacia la misma ruta, pero elimina la extensión .html.

Aquí te explicamos cómo controlar la inclusión de .html en las URL mediante la inclusión de un atributo cleanUrls:

"hosting": {
  // ...

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

Controla la inclusión de barras finales

Opcional
El atributo trailingSlash te permite controlar si las URL de contenido estático deben incluir barras finales.

  • Si el valor es true, Hosting redireccionará las URL de modo que tengan una barra final.
  • Si el valor es false, Hosting redireccionará las URL de modo que no tengan una barra final.
  • Si no se especifica un valor, Hosting solo incluirá barras finales en los archivos de índice del directorio (p. ej., about/index.html).

Aquí te explicamos cómo controlar las barras finales mediante la inclusión de un atributo trailingSlash:

"hosting": {
  // ...

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

El atributo trailingSlash no afecta las reescrituras en el contenido dinámico que entrega Cloud Functions o Cloud Run.

Comparación de patrones glob

Las opciones de configuración de Firebase Hosting usan ampliamente la notación de concordancia de patrones glob con extglob, de manera similar a la forma en que Git maneja las reglas gitignore, y Bower maneja las reglas ignore. En esta página de wiki, se brinda una referencia más detallada. Sin embargo, aquí te ofrecemos una explicación de los ejemplos que se usaron en esta página:

  • firebase.json: Solo coincide con el archivo firebase.json ubicado en la raíz del directorio public.

  • **: Coincide con cualquier archivo o carpeta ubicado en un subdirectorio arbitrario.

  • *: Solo coincide con los archivos y las carpetas ubicadas en la raíz del directorio public.

  • **/.*: Coincide con cualquier archivo que comience con . (generalmente, estos son archivos ocultos, como la carpeta .git) ubicado en un subdirectorio arbitrario.

  • **/node_modules/**: Coincide con cualquier archivo o carpeta ubicado en un subdirectorio arbitrario de una carpeta node_modules, que puede estar en un subdirectorio arbitrario del directorio public.

  • **/*.@(jpg|jpeg|gif|png): Coincide con cualquier archivo ubicado en un subdirectorio arbitrario cuya terminación coincida exactamente con una de las siguientes extensiones: .jpg, .jpeg, .gif o .png.

Ejemplo completo de la configuración de Hosting

Este es un ejemplo completo de la configuración de firebase.json para Firebase Hosting. Ten en cuenta que un archivo firebase.json también puede contener configuraciones de otros servicios de 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",

  }
}