Publish with SvelteKit
SvelteKit can publish the declaration as an ordinary static file with the static adapter.
Add the declaration
Create this directory and file in the SvelteKit project’s static directory:
static/
.well-known/
josh
A participant affirming Josh identity:
{
"version": 1,
"josh": true
}
josh may instead be false for Declined Josh Identity, or omitted for Undeclared Josh Identity. The implementation guide defines those three declarations. Do not invent other values. Publishing any valid version 1 declaration establishes participation according to RFC-JOSH-0002.
SvelteKit copies files from static into the adapter-static output. After a normal build with prerender enabled:
vite build
the generated site should contain:
build/
.well-known/
josh
The deployed resource is then:
https://example.invalid/.well-known/josh
Other adapters may place or serve static files differently. Do not assume those paths without checking that adapter’s docs.
Check the SvelteKit build
Before deploying, confirm that the static adapter produced the exact extensionless file:
test -f build/.well-known/josh
cat build/.well-known/josh
You can also check the local preview server after a build:
vite preview
Then:
curl -i http://localhost:4173/.well-known/josh
The local check confirms that the resource exists at the expected path. Always repeat the check against the deployed site because production response headers are controlled by the hosting platform. vite preview does not set Content-Type: application/json for the extensionless file.
Serve it as JSON
RFC-JOSH-0002 associates the declaration with the application/json media type. A server SHOULD return:
Content-Type: application/json
SvelteKit does not choose that media type for an extensionless file in the static-adapter case. The host does.
Sites published below the origin root
A well-known URI belongs at the root of an origin.
For a site whose public URL is:
https://example.invalid/blog/
the Joshternet declaration is still:
https://example.invalid/.well-known/josh
It is not:
https://example.invalid/blog/.well-known/josh
SvelteKit paths.base does not move the well-known URI. A site that only controls a path under someone else’s origin cannot declare for that origin through this protocol.
Check the deployed URL
Check the live origin with Check a declaration.
Or check the live URL directly:
curl -i https://example.invalid/.well-known/josh
Confirm all of the following:
/.well-known/joshexists at the root of the participating origin- HTTP
GETnormally returns200 OK - the response uses
Content-Type: application/jsonwhen the hosting platform permits it - the response body is valid JSON
versionis the integer1josh, when present, is a JSON Boolean- the public path has no
.jsonextension - the canonical path has no trailing slash
- any redirect that is followed remains on the same origin
- the resource is readable without authentication or client-side JavaScript
Publishing the file declares participation. It does not separately notify JoshBot or require registration with joshternet.org.
Stop publishing
To stop declaring participation from a SvelteKit site, remove static/.well-known/josh, rebuild, and redeploy so the live origin no longer serves a valid declaration. Remove any host header rules that exist only for that path.
A deliberate 404 Not Found or 410 Gone at /.well-known/josh indicates that no declaration is currently published. Temporary timeouts, TLS problems, DNS failures, and server errors do not mean the participant intentionally left.
Tested
- Platform: SvelteKit 2 +
@sveltejs/adapter-static(static/→build/) - Verified: 2026-10-06
- Protocol: RFC-JOSH-0002 version 1