Mengonfigurasi perilaku hosting

Dengan Firebase Hosting, Anda dapat mengonfigurasi perilaku hosting yang disesuaikan, termasuk halaman error , pengalihan, penulisan ulang, dan header kustom. Anda juga dapat menentukan file yang akan di-deploy dari direktori project ke project Firebase Anda.

Menentukan konfigurasi Firebase Hosting di file firebase.json.

Temukan file firebase.json di root direktori project Anda. Firebase secara otomatis membuat file firebase.json saat Anda menjalankan perintah firebase init.

Anda dapat menemukan contoh konfigurasi firebase.json lengkap (hanya mencakup Firebase Hosting) di bagian bawah halaman ini. Perhatikan bahwa file firebase.json juga dapat berisi konfigurasi untuk layanan Firebase lainnya.

Anda dapat memeriksa konten firebase.json yang di-deploy menggunakan REST API Firebase Hosting.

Urutan prioritas respons Hosting

Berbagai opsi konfigurasi Firebase Hosting yang diuraikan di halaman ini terkadang dapat tumpang tindih. Jika ada konflik, Hosting menentukan responsnya menggunakan urutan prioritas berikut:

  1. Namespace yang dipesan yang dimulai dengan segmen jalur /__/*
  2. Pengalihan yang dikonfigurasi
  3. Konten statis yang sama persis
  4. Penulisan ulang yang dikonfigurasi
  5. Halaman 404 kustom
  6. Halaman 404 default

Menentukan file yang akan di-deploy

Atribut default — public dan ignore — disertakan dalam file firebase.json default menentukan jenis file di direktori project yang harus di-deploy ke project Firebase.

Konfigurasi hosting default dalam file firebase.json akan terlihat seperti ini:

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

public

Wajib
Atribut public menentukan jenis direktori yang akan di-deploy ke Firebase Hosting. Nilai default-nya adalah direktori bernama public, tetapi Anda dapat menentukan semua lokasi direktori selama lokasi tersebut ada di direktori project Anda.

Berikut adalah nama direktori default yang ditentukan untuk di-deploy:

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

  // ...
}

Anda dapat mengubah nilai default ke direktori yang ingin Anda deploy:

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

  // ...
}

ignore

Opsional
Atribut ignore menentukan file yang akan diabaikan saat di-deploy. Atribut ini bisa menggunakan glob dengan cara yang sama seperti Git menangani .gitignore.

Berikut ini adalah nilai default yang akan diabaikan oleh file:

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

Menyesuaikan halaman 404/Tidak Ditemukan

Opsional
Anda dapat menayangkan error 404 Not Found kustom saat pengguna mencoba mengakses halaman yang tidak ada.

Buat file baru di direktori public project, beri nama 404.html, lalu tambahkan konten 404 Not Found kustom ke file tersebut.

Firebase Hosting akan menampilkan konten halaman 404.html kustom ini jika browser memicu error 404 Not Found di domain atau subdomain Anda.

Mengonfigurasi pengalihan

Opsional
Gunakan pengalihan URL untuk mencegah munculnya link rusak ketika Anda memindahkan halaman atau perlu mempersingkat URL. Misalnya, Anda dapat mengalihkan browser dari example.com/team ke example.com/about.html.

Tentukan pengalihan URL dengan membuat atribut redirects yang berisi array objek (disebut "aturan pengalihan"). Di setiap aturan, tentukan pola URL yang, jika cocok dengan jalur URL permintaan, akan memicu Hosting untuk merespons dengan pengalihan ke URL tujuan yang ditentukan.

Berikut adalah contoh atribut redirects:

"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
  }, {
    // A regular expression-based redirect equivalent to the above behavior
    "regex": "/firebase/.*",
    "destination": "https://firebase.google.com/",
    "type": 302
  } ]
}

Atribut redirects berisi array aturan pengalihan, yang mana setiap aturan harus menyertakan kolom berikut:

  • source atau regex — Menentukan pola URL yang, jika cocok dengan URL permintaan, akan memicu Hosting untuk menerapkan pengalihan

  • destination — Menentukan URL statis yang dapat berupa jalur relatif atau absolut

  • type — Menentukan kode respons HTTP

    • Gunakan jenis 301 untuk 'Dipindahkan Secara Permanen'
    • Gunakan jenis 302 untuk 'Ditemukan' (Pengalihan Sementara)

Firebase Hosting membandingkan nilai source atau regex terhadap semua jalur URL di awal setiap permintaan (sebelum browser menentukan apakah file atau folder ada di jalur tersebut). Jika kecocokan ditemukan, server asal Firebase Hosting akan mengirimkan respons pengalihan HTTP yang menginformasikan browser untuk membuat permintaan baru di URL destination.

Mengambil segmen URL untuk pengalihan

Opsional
Terkadang, Anda mungkin perlu mengambil segmen tertentu dari pola URL aturan pengalihan (nilai source atau regex), lalu menggunakan kembali segmen ini di jalur destination aturan tersebut.

Mengambil segmen URL saat menggunakan glob

Jika menggunakan kolom source (yakni menentukan glob untuk pola URL Anda), Anda dapat mengambil segmen dengan menyertakan awalan : untuk mengidentifikasi segmen. Jika Anda juga perlu mengambil jalur URL yang tersisa di belakang segmen itu, langsung sertakan * di belakang segmen itu. Contoh:

"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 captured by the "source" value
    "type": 301
  } ]
}

Mengambil segmen URL saat menggunakan ekspresi reguler RE2

Jika menggunakan kolom regex (yakni menentukan ekspresi reguler RE2 untuk pola URL), Anda dapat mengambil segmen menggunakan grup tangkapan RE2 yang bernama atau tanpa nama. Grup tangkapan bernama dapat digunakan di kolom destination dengan awalan :, sementara grup tangkapan tanpa nama dapat dirujuk oleh indeks numeriknya dalam nilai regex, yang diindeks dari 1. Contoh:

"hosting": {
  // ...

  "redirects": [ {
    "regex": "/blog/(?P<post>.+)",  // if you're familiar with PCRE, be aware that RE2 requires named capture groups to begin with ?P
    "destination": "https://blog.myapp.com/:post",  // includes the entire URL segment identified and captured by the `regex` value
    "type": 301
  }, {
    "regex": "/users/(\d+)/profile",  // uses the \d directive to only match numerical path segments
    "destination": "/users/:1/newProfile",  // the first capture group to be seen in the `regex` value is named 1, and so on
    "type": 301
  } ]
}

Mengonfigurasi penulisan ulang

Opsional
Gunakan penulisan ulang guna menampilkan konten yang sama untuk beberapa URL. Penulisan ulang sangat berguna dengan pencocokan pola karena Anda bisa menerima URL apa pun yang cocok dengan pola dan mengizinkan kode sisi klien memutuskan apa yang akan ditampilkan.

Anda juga dapat menggunakan penulisan ulang untuk mendukung aplikasi yang menggunakan pushState HTML5 untuk navigasi. Saat browser mencoba membuka jalur URL yang cocok dengan pola URL source atau regex yang ditentukan, browser tersebut akan diberi konten file di URL destination.

Tentukan penulisan ulang URL dengan membuat atribut rewrites yang berisi array objek (disebut "aturan penulisan ulang"). Di setiap aturan, tentukan pola URL yang, jika cocok dengan jalur URL permintaan, akan memicu Hosting untuk merespons seolah-olah layanan diberi URL tujuan yang ditentukan.

Berikut adalah contoh atribut rewrites:

"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"
  }, {
    // A regular expression-based rewrite equivalent to the above behavior
    "regex": "/foo(/.*)?",
    "destination": "/index.html"
  }, {
    // Excludes specified pathways from rewrites
    "source": "!/@(js|css)/**",
    "destination": "/index.html"
  } ]
}

Atribut rewrites berisi array aturan penulisan ulang, yang mana setiap aturan harus menyertakan kolom berikut:

  • source atau regex - Menentukan pola URL yang, jika cocok dengan URL permintaan, akan memicu Hosting untuk menerapkan penulisan ulang

  • destination - Menentukan file lokal yang harus ada

Firebase Hosting hanya menerapkan aturan penulisan ulang jika file atau direktori tidak ada di jalur URL yang cocok dengan pola URL source atau regex yang ditentukan. Ketika aturan penulisan ulang dipicu, browser akan menampilkan konten aktual file destination yang ditentukan, bukan pengalihan HTTP.

Permintaan langsung ke fungsi

Anda dapat menggunakan rewrites untuk menayangkan fungsi dari URL Firebase Hosting. Contoh berikut adalah kutipan dari penayangan konten dinamis menggunakan Cloud Functions.

Misalnya, untuk mengalihkan semua permintaan dari /bigben halaman di situs Hosting Anda untuk menjalankan fungsi bigben.

"hosting": {
  // ...

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

Setelah menambahkan aturan penulisan ulang ini dan men-deploy ke Firebase (menggunakan firebase deploy), fungsi Anda dapat dijangkau melalui URL berikut:

  • Subdomain Firebase Anda: projectID.web.app/bigben dan projectID.firebaseapp.com/bigben

  • Semua domain kustom yang terhubung: custom-domain/bigben

Permintaan langsung ke container Cloud Run

Anda dapat menggunakan rewrites untuk mengakses container Cloud Run dari URL Firebase Hosting. Contoh berikut adalah kutipan dari penayangan konten dinamis menggunakan Cloud Run.

Misalnya, untuk mengarahkan semua permintaan dari halaman /helloworld di situs Hosting Anda untuk memicu startup dan menjalankan instance container 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)
   }
 } ]
}

Setelah menambahkan aturan penulisan ulang ini dan men-deploy ke Firebase (menggunakan firebase deploy), image container Anda dapat dijangkau melalui URL berikut:

  • Subdomain Firebase Anda: projectID.web.app/helloworld dan projectID.firebaseapp.com/helloworld

  • Semua domain kustom yang terhubung: custom-domain/helloworld

Anda dapat menggunakan rewrites untuk membuat Dynamic Links domain kustom. Buka dokumentasi Dynamic Links untuk mengetahui informasi terperinci seputar penyiapan domain kustom untuk Dynamic Links.

Misalnya, Anda dapat:

  • Gunakan domain Anda hanya untuk Dynamis 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
      } ]
    }
    
  • Menentukan awalan jalur yang ingin Anda gunakan untuk Dynamis 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
      } ]
    }
    

Mengonfigurasi Dynamic Links di file firebase.json Anda memerlukan hal berikut:

  • Atribut appAssociation yang disetel ke AUTO.

    • Default untuk appAssociation adalah AUTO jika Anda tidak menyertakan atribut pada konfigurasi.
    • Saat atribut ini disetel ke AUTO, Hosting secara dinamis membuat file assetlinks.json dan apple-app-site-association saat diminta.
  • Atribut rewrites untuk Dynamic Links yang berisi array aturan penulisan ulang, di mana setiap aturan harus menyertakan:

    • source yang menetapkan jalur yang ingin Anda gunakan untuk Dynamic Links

      • Tidak seperti aturan yang menulis ulang jalur ke URL, aturan penulisan ulang Dynamic Link tidak dapat berisi ekspresi reguler.
    • Atribut dynamicLinks yang disetel ke true

Mengonfigurasi header

Opsional
Dengan header, klien dan server dapat meneruskan informasi tambahan bersama dengan permintaan atau respons. Beberapa kumpulan header dapat memengaruhi cara browser menangani halaman dan kontennya, termasuk kontrol akses, autentikasi, caching, dan encoding.

Tentukan header respons kustom dan khusus untuk file dengan membuat atribut headers yang berisi array objek header. Di setiap objek, tentukan pola URL yang, jika cocok dengan jalur URL permintaan, akan memicu Hosting untuk menerapkan header respons kustom yang ditentukan.

Berikut adalah contoh atribut headers:

"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"
    } ]
  }, {
    // A regular expression-based rewrite equivalent to the above behavior
    "regex": ".+/\w+\.(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"
    } ]
  } ]
}

Atribut headers berisi array definisi, di mana setiap definisi harus menyertakan kolom berikut:

  • source atau regex - Menentukan pola URL yang, jika cocok dengan URL permintaan, akan memicu Hosting untuk menerapkan header kustom

  • array (sub -)headers - Menentukan header kustom yang diterapkan oleh Hosting ke jalur permintaan. Setiap array sub-header harus menyertakan key dan value yang ditentukan.

Anda dapat mempelajari Cache-Control lebih lanjut di bagian Hosting yang menjelaskan cara menayangkan konten dinamis dan menghosting microservice.

Anda juga dapat mempelajari header CORS lebih lanjut.

Mengontrol ekstensi .html

Opsional
Atribut cleanUrls dapat digunakan untuk mengontrol apakah URL harus menyertakan ekstensi .html atau tidak.

Saat true, Hosting melepas ekstensi .html secara otomatis dari URL file yang diupload. Jika ekstensi .html ditambahkan di permintaan, Hosting melakukan pengalihan 301 ke lokasi yang sama namun menghilangkan ekstensi .html.

Tentukan penyertaan ekstensi .html dengan menyertakan atribut cleanUrls di dalam hosting pada file firebase.json Anda. Contoh:

"hosting": {
  // ...

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

Mengontrol garis miring penutup

Opsional
Atribut trailingSlash dapat digunakan untuk mengontrol apakah URL harus menyertakan garis miring penutup atau tidak.

  • Saat true, Hosting mengalihkan URL untuk menambahkan garis miring penutup.
  • Saat false, Hosting mengalihkan URL untuk menghapus garis miring penutup.
  • Jika tidak ditentukan, Hosting hanya menggunakan garis miring penutup untuk file indeks direktori (misalnya, about/index.html).

Tentukan penyertaan garis miring penutup dengan menyertakan atribut trailingSlash di dalam hosting pada file firebase.json Anda. Contoh:

"hosting": {
  // ...

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

Pencocokan pola glob

Opsi konfigurasi Firebase Hosting seringkali memanfaatkan notasi pencocokan pola glob dengan extglob, mirip dengan cara Git menangani aturan gitignore dan Bower menangani aturan ignore. Halaman wiki ini adalah referensi yang lebih detail, tetapi berikut ini adalah penjelasan dari contoh yang digunakan di halaman ini:

  • firebase.json — Hanya mencocokkan file firebase.json di root direktori public

  • ** — Mencocokkan file atau folder apa pun di sub-direktori arbitrer

  • * — Hanya mencocokkan file dan folder di root dari direktori public

  • **/.* — Mencocokkan file yang diawali dengan . (biasanya file tersembunyi, seperti di folder.git) di sub-direktori arbitrer

  • **/node_modules/** — Mencocokkan file atau folder apa pun di sub-direktori arbitrer dari folder node_modules, yang dengan sendirinya juga bisa berada di dalam sub-direktori arbitrer dari direktori public

  • **/*.@(jpg|jpeg|gif|png) — Mencocokkan file apa pun di sub-direktori arbitrer yang diakhiri dengan salah satu akhiran berikut: .jpg, .jpeg, .gif, atau .png

Contoh konfigurasi Hosting lengkap

Berikut adalah contoh konfigurasi firebase.json lengkap untuk Firebase Hosting. Perhatikan bahwa file firebase.json juga dapat berisi konfigurasi untuk layanan Firebase lainnya.

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

  }
}