Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 27 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,10 @@ and the [`verified-fetch` library](https://github.com/ipfs/helia-verified-fetch)
within a [Service Worker](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API)
to facilitate direct verified retrieval of content-addressed data.

A Service Worker is registered on the initial page load, and then intercepts HTTP requests
for content stored on IPFS paths such as `/ipfs/*` (immutable) and
`/ipns/*` (mutable) and returns
[`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) objects
to the browser.
A Service Worker is registered on the initial page load, and then intercepts
HTTP requests for content stored on IPFS paths such as `/ipfs/*` (immutable) and
`/ipns/*` (mutable) and returns [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response)
objects to the browser.

It functions as an IPFS gateway within the browser, offering enhanced security
([hash verification](https://docs.ipfs.tech/concepts/content-addressing/)
Expand Down Expand Up @@ -98,15 +97,18 @@ With reverse-proxy:
Without reverse-proxy:
* `http://localhost:8345` - The service worker gateway front-end served directly with esbuild.

For the above URLs with reverse-proxy, the reverse proxy ensures subdomain support. This ensures you can access URLs like `https://<hash>.ipfs.localhost:<port>/` and `https://<dnslink>.ipns.localhost:<port>/`
For the above URLs with reverse-proxy, the reverse proxy ensures subdomain
support. This ensures you can access URLs like `https://<hash>.ipfs.localhost:<port>/`
and `https://<dnslink>.ipns.localhost:<port>/`

As you type in a content path, you will be redirected to appropriate URL (typically that means [subdomain style resolution](https://docs.ipfs.tech/how-to/gateway-best-practices/#use-subdomain-gateway-resolution-for-origin-isolation)).
As you type in a content path, you will be redirected to appropriate URL
(typically that means [subdomain style resolution](https://docs.ipfs.tech/how-to/gateway-best-practices/#use-subdomain-gateway-resolution-for-origin-isolation)).

For more information about local development setup, see [/docs/DEVELOPMENT.md](/docs/DEVELOPMENT.md).

### Try hosted instance

We provide a public good instance of this projct configured to run in [subdomain mode](https://docs.ipfs.tech/how-to/address-ipfs-on-web/#subdomain-gateway),
We provide a public good instance of this projct configured to run in[subdomain mode](https://docs.ipfs.tech/how-to/address-ipfs-on-web/#subdomain-gateway),
aiming to be a drop-in replacement for `dweb.link`:

- 🚧 **WIP: alpha quality** https://inbrowser.link hosts the `release` branch, with a stable [release](https://github.com/ipfs/service-worker-gateway/releases)
Expand All @@ -120,21 +122,31 @@ aiming to be a drop-in replacement for `ipfs.io`:

#### Deploying to `production` and `staging`

Deploying to [production](https://github.com/ipfs/service-worker-gateway/actions/workflows/deploy-to-production.yml) and [staging](https://github.com/ipfs/service-worker-gateway/actions/workflows/deploy-to-staging.yml) is done by manually running the deployment action and passing the release version to the action.
Deploying to [production](https://github.com/ipfs/service-worker-gateway/actions/workflows/deploy-to-production.yml)
and [staging](https://github.com/ipfs/service-worker-gateway/actions/workflows/deploy-to-staging.yml)
is done by manually running the deployment action and passing the release
version to the action.

## Manual Service Worker Deregistration

In some cases, you might want to manually unregister or remove the Helia service worker from your browser. This can be useful for debugging purposes or to ensure a clean state.
In some cases, you might want to manually unregister or remove the Helia service
worker from your browser. This can be useful for debugging purposes or to ensure
a clean state.

You can instruct the service worker to unregister itself by appending the `?ipfs-sw-unregister=true` query parameter to the URL of any page controlled by the service worker.
You can instruct the service worker to unregister itself by appending the
`?ipfs-sw-unregister=true` query parameter to the URL of any page controlled by
the service worker.

For example, if the service worker is active for `https://example.com`, navigating to `https://example.com/?ipfs-sw-unregister=true` will cause the service worker to unregister itself and attempt to reload all controlled clients (browser tabs).
For example, if the service worker is active for `https://example.com`,
navigating to `https://example.com/?ipfs-sw-unregister=true` will cause the
service worker to unregister itself and attempt to reload all controlled clients
(browser tabs).

This option is also available via a button on the service worker's configuration page (`#/ipfs-sw-config`).
This option is also available via a button on the service worker's configuration
page (`#/ipfs-sw-config`).

## License

This project is dual-licensed under
`SPDX-License-Identifier: Apache-2.0 OR MIT`
This project is dual-licensed under `SPDX-License-Identifier: Apache-2.0 OR MIT`

See [LICENSE](./LICENSE) for more details.
3 changes: 1 addition & 2 deletions build.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ function gitRevision () {
}

/**
* Inject all ipfs-sw-*.html pages (not index.html and not ipfs-sw-first-hit.html) in the dist folder with CSS, git revision, and logo.
* Inject all ipfs-sw-*.html pages (not index.html) in the dist folder with CSS, git revision, and logo.
*
* @param {esbuild.Metafile} metafile - esbuild's metafile to extract output file names
* @param {string} revision - Pre-computed Git revision string
Expand Down Expand Up @@ -343,7 +343,6 @@ export const buildOptions = {
'src/index.tsx',
'src/sw.ts',
'src/app.tsx',
'src/error.tsx',
'src/ipfs-sw-*.ts',
'src/ipfs-sw-*.css'
],
Expand Down
10 changes: 7 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,16 @@ func redirectToHelia(w http.ResponseWriter, r *http.Request) {

func ipfsLikeHandler(w http.ResponseWriter, r *http.Request) {
if fileExists(r.URL.Path) {
// Serve the embedded file.
// Serve the embedded file
distHandler.ServeHTTP(w, r)
return
}
// Otherwise hand off to the SW via redirect.
redirectToHelia(w, r)

// Otherwise serve the index file
http.ServeFile(w, r, "dist/index.html")

// Otherwise hand off to the SW via redirect
// redirectToHelia(w, r)
}

// -----------------------------------------------------------------------------
Expand Down
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"@helia/http": "^3.0.8",
"@helia/interface": "^6.0.2",
"@helia/routers": "^4.0.3",
"@helia/verified-fetch": "^4.0.1",
"@helia/verified-fetch": "^4.0.3",
"@libp2p/crypto": "^5.1.13",
"@libp2p/dcutr": "^3.0.7",
"@libp2p/identify": "^4.0.7",
Expand All @@ -80,6 +80,8 @@
"multiformats": "^13.4.1",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-icons": "^5.5.0",
"react-router-dom": "^7.9.5",
"tachyons": "^4.12.0",
"weald": "^1.1.1"
},
Expand All @@ -105,8 +107,7 @@
"patch-package": "^8.0.0",
"playwright": "^1.45.3",
"rimraf": "^6.0.1",
"wait-on": "^9.0.1",
"wherearewe": "^2.0.1"
"wait-on": "^9.0.1"
},
"sideEffects": [
"*.css"
Expand Down
12 changes: 10 additions & 2 deletions playwright.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,14 @@ export default defineConfig({
{
name: 'firefox',
use: {
...devices['Desktop Firefox']
...devices['Desktop Firefox'],
launchOptions: {
firefoxUserPrefs: {
// if we redirect too quickly, too many times, Firefox deletes all
// site application data (e.g. the service worker)
'privacy.bounceTrackingProtection.mode': 0
}
}
}
},
{
Expand Down Expand Up @@ -91,7 +98,8 @@ export default defineConfig({
},
launchOptions: {
firefoxUserPrefs: {
'dom.serviceWorkers.enabled': false
'dom.serviceWorkers.enabled': false,
'privacy.bounceTrackingProtection.mode': 0
}
},
/**
Expand Down
7 changes: 5 additions & 2 deletions public/_kubo_redirects
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/ipns/* /ipfs-sw-first-hit.html 200
/ipfs/* /ipfs-sw-first-hit.html 200
# https://specs.ipfs.tech/http-gateways/web-redirects-file/
# Used in the e2e test suite - different to _redirects because kubo handles 302s
# and the :splat differently to cloudflare
/ipns/* /index.html 200
/ipfs/* /index.html 200
/* /index.html 200
6 changes: 4 additions & 2 deletions public/_redirects
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
/ipns/* /ipfs-sw-first-hit.html/ipns/:splat 302
/ipfs/* /ipfs-sw-first-hit.html/ipfs/:splat 302
# https://specs.ipfs.tech/http-gateways/web-redirects-file/
# https://developers.cloudflare.com/pages/configuration/redirects/
/ipfs/* /index.html/:splat 302
/ipns/* /index.html/:splat 302
10 changes: 2 additions & 8 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -103,16 +103,10 @@
</style>
</head>
<body>
<div class="loading-container loading-indicator-js hidden">
<div class="loading-container loading-indicator-js">
<div class="loading-animation"></div>
</div>
<div id="root" class="sans-serif f5"></div>
<script>
window.addEventListener('DOMContentLoaded', () => {
document.querySelector('.loading-indicator-js').classList.add('hidden')
document.getElementById('root').style.display = 'block'
})
</script>
<div id="root" class="sans-serif charcoal f5"></div>
<%= JS_SCRIPT_TAG %>
</body>
</html>
23 changes: 0 additions & 23 deletions public/ipfs-sw-first-hit.html

This file was deleted.

9 changes: 9 additions & 0 deletions src/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,12 @@ form {
.cursor-disabled {
cursor: not-allowed;
}

header a {
text-decoration: none;
color: var(--aqua);
}

header a:hover {
color: #EEE;
}
Loading
Loading