Configura el comportamiento del hosting

Firebase Hosting te permite configurar comportamientos de hosting personalizados, como páginas de error, redireccionamientos, reescrituras y encabezados personalizados. Además, te permite especificar qué archivos del directorio del proyecto quieres implementar en el proyecto de Firebase.

Define la configuración de Firebase Hosting en el archivo firebase.json.

Encontrarás el archivo firebase.json en la raíz del directorio del proyecto. Cuando ejecutas el comando firebase init, Firebase crea automáticamente el archivo firebase.json.

.

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 mediante 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 concordancia exacta
  4. Reescrituras configuradas
  5. Página 404 personalizada
  6. Página 404 predeterminada

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 pasar por alto en la implementación. Puede usar el patrón glob de la misma manera en 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 (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
  ]
}

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 trasladaste una página, o bien para acortar una URL. Por ejemplo, puedes redireccionar a un navegador de example.com/team a example.com/about.html.

Para especificar un redireccionamiento de URL, incluye un atributo redirects en la sección hosting del archivo firebase.json. Por ejemplo:

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

El atributo redirects contiene una matriz de reglas de redireccionamiento. En esta, cada regla debe incluir lo siguiente:

  • Una source que especifique un patrón glob

  • Un destination, que corresponde a una URL estática que puede ser una ruta de acceso relativa o absoluta

  • Un type que especifique el código de respuesta HTTP

Firebase Hosting compara el valor source 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 la ruta). Si se encuentra una concordancia, el servidor de origen de Firebase Hosting enviará una respuesta de redireccionamiento HTTP que indicará al navegador que debe realizar una solicitud nueva en la URL destination.

Por último, el valor type indica el código de respuesta HTTP específico que se proporciona y puede ser 301 para “Moved Permanently” o 302 para “Found” (redireccionamiento temporal).

Captura segmentos de URL para los redireccionamientos

Opcional
En ocasiones, es posible que debas capturar segmentos específicos de una URL de redireccionamiento source y, luego, volver a utilizarlos en la URL destination.

Para capturar estos segmentos, identifícalos con el prefijo :. Además, incluye un * justo después del segmento si necesitas capturar la ruta de URL que le sucede. Por ejemplo:

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

Configura reescrituras

Opcional
Usa una reescritura para mostrar el mismo contenido en varias URL. Las reescrituras son especialmente útiles con la concordancia 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 el método pushState de HTML5 en la navegación. Cuando un navegador intenta abrir una URL source específica, se le proporcionará el contenido del archivo que se encuentra en la URL destination.

Para especificar las reescrituras de URL, incluye un atributo rewrites en la sección hosting del archivo firebase.json. Por ejemplo:

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

El atributo rewrites contiene una matriz de reglas de reescritura. En esta, cada regla debe incluir lo siguiente:

  • Una source que especifique un patrón glob

  • Un destination, que debe ser un archivo local existente

Firebase Hosting solo aplicará una regla de reescritura si la ruta de source no dirige a un archivo o directorio existente. Cuando se activa una regla, el navegador muestra el contenido del archivo destination especificado, en lugar de un redireccionamiento HTTP.

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

  // Add the "rewrites" attribute within "hosting"
  "rewrites": [ {
    "source": "/bigben",
    "function": "bigben"
  } ]
}

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

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

  • Cualquier dominio personalizado conectado: custom-domain/bigben

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

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

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

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

  • Cualquier dominio personalizado conectado: custom-domain/helloworld

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.

Por ejemplo, puedes hacer lo siguiente:

  • Usar el dominio 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": "/**",  // Dynamic Links start with "https://<your-domain>/"
        "dynamicLinks": true
      } ]
    }
    
  • Especifica los prefijos de ruta que quieras usar para los 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
      } ]
    }
    

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

  • Un atributo appAssociation configurado como AUTO

    • El valor predeterminado de appAssociation será AUTO si no se incluye el atributo en la configuración.
    • Si el atributo se configura como AUTO, Hosting generará los archivos assetlinks.jsonapple-app-site-association de manera dinámica cuando estos se soliciten.
  • Un atributo rewrites para Dynamic Links con una matriz de reglas de reescritura. En esta, cada regla debe incluir lo siguiente:

    • Un source en el que se especifique la ruta que se va a usar para los 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.
    • Un atributo dynamicLinks configurado 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.

Incluye un atributo headers en la sección hosting del archivo firebase.json para especificar encabezados de respuesta personalizados y específicos de un archivo. Por ejemplo:

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

El atributo headers contiene un arreglo de definiciones. En este, cada definición debe incluir lo siguiente:

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.

Además, puedes obtener más información sobre los encabezados 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.

Puedes incluir un atributo cleanUrls en la sección hosting del archivo firebase.json para especificar la inclusión de extensiones .html. Por ejemplo:

"hosting": {
  // ...

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

Controla la inclusión de barras finales

Opcional
El atributo trailingSlash te permite controlar la inclusión de barras al final de las URL.

  • 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).

Puedes incluir un atributo trailingSlash en la sección hosting del archivo firebase.json para especificar la inclusión de barras finales. Por ejemplo:

"hosting": {
  // ...

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

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

  }
}