Jamdesk Documentation logo

Cloudflare Workers

Proxy delle richieste /docs tramite un Worker Cloudflare verso il tuo sito Jamdesk, con configurazione di route e cache.

Un Cloudflare Worker intercetta le richieste a /docs sul tuo dominio, le riscrive verso il tuo sottodominio Jamdesk e restituisce la risposta direttamente all'edge, senza bisogno di un server di origine. Puoi creare automaticamente lo scheletro del Worker con npx jamdesk deploy-proxy cloudflare oppure configurarlo manualmente come descritto di seguito.

Come funziona

Il Worker inoltra le richieste al tuo sottodominio Jamdesk e invia il tuo dominio nell'header X-Jamdesk-Forwarded-Host, che Jamdesk usa per verificare il dominio e applicare le relative impostazioni. È una configurazione una tantum: se in seguito modifichi il dominio o la configurazione nel dashboard, non è necessario aggiornare il Worker.

Prerequisiti

  • Un account Cloudflare con il dominio configurato
  • Wrangler CLI v3.0 o superiore installato
  • Il tuo sottodominio Jamdesk (disponibile nelle impostazioni del dashboard)
  • Il tuo dominio personalizzato aggiunto al progetto nel dashboard Jamdesk (il Worker restituisce 403 finché il dominio non è registrato e verificato)
  • Un record DNS proxied (cloud arancione) sull'hostname che serve la documentazione. I Worker vengono eseguiti solo sui record proxied, quindi anche un dominio che non ospita altro deve averne uno: aggiungi un record AAAA segnaposto che punti a 100:: e impostalo come proxied.

Configurazione rapida con CLI

Il modo più veloce per configurare il tuo Cloudflare Worker:

npx jamdesk deploy-proxy cloudflare

Questo comando interattivo:

  1. Verifica che wrangler 3.0 o superiore sia installato
  2. Verifica il tuo account Cloudflare e mostra i domini disponibili
  3. Risolve il sottodominio Jamdesk dal progetto collegato in docs.json
  4. Ti consente di selezionare il dominio di destinazione dalle tue zone Cloudflare
  5. Genera tutti i file necessari
  6. Esegue facoltativamente il deploy su Cloudflare

Se hai accesso a più account Cloudflare, cosa comune per agenzie o team, la CLI ti chiede di sceglierne uno prima della selezione della zona. Seleziona l'account proprietario del dominio su cui stai eseguendo il deploy: le route dei Worker possono essere create solo per i domini dell'account selezionato.

Configurazione non interattiva

Per eseguire il comando senza prompt, ad esempio in CI o da uno script, passa le risposte come flag:

jamdesk deploy-proxy cloudflare --slug myproject --domain example.com --yes

--yes genera i file del Worker e termina. Non esegue mai il deploy: la zona viene dedotta dal dominio invece di essere verificata rispetto al tuo account Cloudflare, quindi rendere attiva questa configurazione resta un passaggio esplicito. Completa con:

cd cloudflare-worker
npx wrangler deploy

Con --yes la CLI non può mostrare prompt, quindi deve conoscere il tuo sottodominio. Lo legge dal progetto collegato in docs.json; se il collegamento manca, esegui una volta jamdesk deploy per aggiungerlo, passa --slug esplicitamente oppure il comando terminerà senza fare supposizioni.

Se la directory di output esiste già, --yes termina senza sostituirla. Aggiungi --force per sovrascriverla oppure --output-dir per scrivere in un'altra posizione.

OpzioneDescrizione
--slugIl tuo sottodominio Jamdesk, la X in X.jamdesk.app (salta il rilevamento automatico)
--domainDominio di destinazione (ad esempio, yoursite.com)
--pathPrefisso del percorso; deve corrispondere esattamente al sottopercorso del dashboard (predefinito: /docs)
--output-dirDirectory di output (predefinita: cloudflare-worker/)
--skip-deploySalta il prompt "deploy now?" durante un'esecuzione interattiva (--yes non esegue mai il deploy)
--forceSovrascrive la directory di output se esiste già
--yesRisponde a ogni prompt con il valore predefinito (modalità CI). Non esegue mai il deploy e non sovrascrive mai una directory esistente: combina con --force per farlo

Se preferisci una configurazione manuale, continua con i passaggi seguenti.


Configurazione manuale

Passaggio 1: crea un Worker

Crea una nuova directory per il Worker e inizializzala:

mkdir docs-proxy && cd docs-proxy
npm init -y

Passaggio 2: aggiungi il codice del Worker

Crea index.js con il seguente codice:

index.js
/**
 * Jamdesk Documentation Proxy Worker
 *
 * Generated by: jamdesk deploy-proxy cloudflare
 * Proxies /docs/* requests AND their assets to YOUR_SLUG.jamdesk.app
 *
 * Assets under /_jd/* (images, fonts, branding, analytics) must also be proxied
 * since they use absolute paths in the HTML.
 */

const JAMDESK_HOST = "YOUR_SLUG.jamdesk.app";

// Paths that are always proxied to Jamdesk
const PROXY_PATHS = [
  "/docs",  // Documentation pages
  "/_jd/",  // All Jamdesk assets (images, fonts, branding, analytics)
];

function shouldProxy(pathname) {
  return PROXY_PATHS.some(prefix => {
    // For the docs path, require exact match or prefix with slash (not /docs.json)
    if (prefix === "/docs") {
      return pathname === "/docs" || pathname.startsWith("/docs/");
    }
    return pathname.startsWith(prefix);
  });
}

function proxyToJamdesk(request, url) {
  // Rewrite the request to Jamdesk
  const proxyUrl = new URL(request.url);
  proxyUrl.hostname = JAMDESK_HOST;
  // Pin the scheme: an http:// visitor proxied as http:// gets a 308 from
  // Vercel's edge pointing at JAMDESK_HOST, and redirect:"manual" hands that
  // redirect straight to the browser — bouncing the visitor off this domain.
  proxyUrl.protocol = "https:";
  // Setting .protocol leaves a non-default .port in place, so :8787 (wrangler
  // dev) or Cloudflare's alternate http ports (8080, 8880, 2052…) would follow
  // us to the https upstream and fail there.
  proxyUrl.port = "";

  // Clone headers and add proxy headers
  const headers = new Headers(request.headers);
  headers.set("Host", JAMDESK_HOST);
  headers.set("X-Forwarded-Host", url.hostname);
  headers.set("X-Forwarded-Proto", "https");
  // Custom header for domain verification (Vercel strips standard forwarding headers)
  headers.set("X-Jamdesk-Forwarded-Host", url.hostname);

  // Don't follow redirects — let the browser handle them so the URL updates.
  // Without this, redirects happen internally and the browser URL doesn't change,
  // which causes the sidebar to mis-highlight the active page.
  const proxyRequest = new Request(proxyUrl, {
    method: request.method,
    headers,
    body: request.body,
    redirect: "manual",
  });

  // Cache all content types at Cloudflare edge (CF doesn't cache HTML by default).
  // Cache duration is controlled by upstream Cache-Control headers.
  // Never cache redirects or errors — they must always hit origin.
  return fetch(proxyRequest, {
    cf: {
      cacheEverything: true,
      cacheTtlByStatus: { "300-399": 0, "400-499": 0, "500-599": 0 },
    },
  });
}

export default {
  async fetch(request) {
    const url = new URL(request.url);

    if (shouldProxy(url.pathname)) {
      return proxyToJamdesk(request, url);
    }

    // /_next/ is ambiguous: the customer's root site may itself be a Next.js app
    // serving its own /_next/ assets. Try the origin first and fall back to
    // Jamdesk when the origin doesn't have it (404) or can't answer at all
    // (5xx — a docs-only domain has no real origin, so Cloudflare returns 522).
    // Hashed asset filenames never collide between the two apps.
    if (url.pathname.startsWith("/_next/")) {
      let originResponse;
      try {
        originResponse = await fetch(request);
      } catch (err) {
        // Log rather than swallow: a genuine platform fault and a domain with
        // no origin at all are indistinguishable in `wrangler tail` otherwise.
        console.warn("origin fetch threw, serving from Jamdesk:", err);
        return proxyToJamdesk(request, url);
      }
      if (originResponse.status !== 404 && originResponse.status < 500) {
        return originResponse;
      }
      return proxyToJamdesk(request, url);
    }

    return fetch(request);
  },
};

Sostituisci YOUR_SLUG con il tuo sottodominio Jamdesk effettivo, ad esempio acme se la documentazione è disponibile all'indirizzo acme.jamdesk.app.

Se usi un sottopercorso personalizzato dal dashboard invece del valore predefinito /docs, sostituisci "/docs" con il tuo sottopercorso in PROXY_PATHS e nel controllo di corrispondenza esatta all'interno di shouldProxy(). Il flag --path della CLI esegue questa operazione quando genera il file, ma solo su un template non modificato; la rigenerazione sovrascrive le voci personalizzate aggiunte manualmente a PROXY_PATHS. Se hai personalizzato questo Worker, modifica direttamente le voci /docs.

L'header X-Jamdesk-Forwarded-Host è obbligatorio e un header mancante causa un errore silenzioso: le richieste continuano ad avere esito positivo, ma le pagine vengono servite con noindex e link canonici che puntano a YOUR_SLUG.jamdesk.app invece che al tuo dominio, impedendo ai motori di ricerca di indicizzare la documentazione. Un 403 indica il problema opposto: l'header è presente, ma specifica un dominio non registrato e attivo per questo progetto.

Passaggio 3: configura wrangler.toml

Crea wrangler.toml per configurare il Worker:

wrangler.toml
name = "docs-proxy"
main = "index.js"
compatibility_date = "2024-01-01"

# Serve only via the routes below, not on the public <name>.workers.dev URL —
# that URL is a second way into the same proxy and is worth closing.
workers_dev = false

# Single catch-all route; the worker handles path filtering internally
routes = [
  { pattern = "yoursite.com/*", zone_name = "yoursite.com" },
]

Se il tuo accesso Cloudflare comprende più di un account, aggiungi anche account_id = "<your account id>": in caso contrario wrangler deploy termina invece di scegliere l'account di destinazione. npx wrangler whoami elenca gli ID dei tuoi account.

Se il tuo sito riceve traffico anche su www.yoursite.com, aggiungi una seconda route per fare in modo che il Worker gestisca entrambi:

routes = [
  { pattern = "yoursite.com/*", zone_name = "yoursite.com" },
  { pattern = "www.yoursite.com/*", zone_name = "yoursite.com" },
]

Passaggio 4: esegui il deploy

Esegui il deploy del Worker su Cloudflare:

npx wrangler deploy

Passaggio 5: verifica

Visita https://yoursite.com/docs per verificare che la documentazione venga servita correttamente.

Risoluzione dei problemi

Se hai rinominato il sottopercorso nel dashboard, ad esempio da /docs a /help, ma PROXY_PATHS del Worker contiene ancora solo /docs, le richieste a /help/* non raggiungono mai Jamdesk: passano a fetch(request) e restituiscono 404 dalla tua origine. Nel frattempo /docs/* continua a funzionare, perché Jamdesk serve entrambi i prefissi: proprio per questo il problema è facile da non notare.

Soluzione: aggiungi il nuovo sottopercorso a PROXY_PATHS. Esegui nuovamente jamdesk deploy-proxy cloudflare --path <subpath> se il Worker è ancora un template non modificato, oppure modifica manualmente l'array se lo hai personalizzato.

Wrangler preferisce CLOUDFLARE_API_TOKEN al login OAuth e non può avviare un login OAuth mentre il token è impostato. Questo comando richiede OAuth per elencare le zone del tuo account, quindi termina mostrando la posizione del token invece di fallire all'interno di wrangler.

Wrangler legge anche .env dalla directory da cui lo esegui, quindi il token può essere impostato per wrangler senza trovarsi nella shell: se echo $CLOUDFLARE_API_TOKEN non stampa nulla, il token potrebbe comunque essere presente. Controlla anche la presenza di un .env nella directory corrente.

Soluzione: concedi al token i permessi account:read e zone:read ed esegui nuovamente il comando, oppure eseguilo senza il token:

env -u CLOUDFLARE_API_TOKEN jamdesk deploy-proxy cloudflare

Se il token proviene da un .env, env -u non sarà sufficiente: esegui il comando da una directory priva di tale .env oppure sposta temporaneamente il file.

La CLI mostra i domini disponibili prima della selezione della zona. Se visualizzi "No domains found":

  1. Verifica di aver effettuato l'accesso all'account Cloudflare corretto
  2. Controlla che il dominio sia stato aggiunto e sia attivo nel dashboard Cloudflare
  3. Esegui nuovamente la CLI e seleziona "No" quando ti viene chiesto se vuoi continuare con l'account corrente, per cambiare account

Se hai più account Cloudflare:

  1. Esegui jamdesk deploy-proxy cloudflare
  2. Quando ti viene chiesto di selezionare un account, scegli quello che contiene il tuo dominio
  3. Se hai bisogno di un login completamente diverso, seleziona "Switch to different login"
  4. La CLI eseguirà il logout e ti chiederà di accedere con le credenziali corrette

Questo errore indica che la zona selezionata non corrisponde al tuo account Cloudflare. Potresti:

  • aver selezionato una zona appartenente a un altro account
  • aver rimosso la zona da Cloudflare

Soluzione: esegui nuovamente la CLI e seleziona la zona corretta dall'elenco, oppure passa all'account proprietario della zona.

Assicurati che il pattern della route usi un catch-all: yoursite.com/*, non solo yoursite.com/docs*. La funzione interna shouldProxy() del Worker gestisce il filtraggio dei percorsi.

Due cause comuni:

  1. Il Worker non è in esecuzione. Assicurati che il record DNS sia impostato su Proxied (cloud arancione) in Cloudflare. I Worker vengono eseguiti solo sui record proxied.
  2. Header X-Forwarded-Host mancante. Il Worker deve impostare questo header affinché Jamdesk generi URL corretti per gli asset.

Se visualizzi "Domain is not authorized to serve this content":

  1. Verifica che il dominio sia registrato nel dashboard Jamdesk
  2. Completa la verifica DNS (record TXT) del dominio
  3. Assicurati che l'header X-Jamdesk-Forwarded-Host sia impostato nel codice del Worker
  4. Controlla che il dominio sia associato al progetto corretto

Il dominio deve essere verificato prima che il Worker possa servire la documentazione.

I Worker vengono eseguiti solo sui record DNS proxied (cloud arancione). Se il record A è impostato su "DNS only" (cloud grigio), le richieste passano direttamente all'origine e ignorano completamente il Worker.

Soluzione: imposta il record A come proxied (cloud arancione) nel DNS Cloudflare. Lo stesso vale per i sottodomini: qualsiasi record con una route Worker deve essere proxied.

Jamdesk verifica la proprietà leggendo direttamente i valori del record DNS. Il proxy Cloudflare (cloud arancione) nasconde questi valori, quindi la verifica non può essere completata.

Soluzione:

  1. Imposta il record DNS su DNS only (cloud grigio)
  2. Attendi il completamento della verifica, quando lo stato diventa active nel dashboard
  3. Imposta nuovamente il record su Proxied (cloud arancione) affinché il Worker venga eseguito

In breve: cloud grigio per verificare → cloud arancione per servire.

Jamdesk serve l'HTML della documentazione con Cache-Control: no-store, quindi Cloudflare non memorizza le pagine nella cache all'edge (cf-cache-status: BYPASS). Ogni richiesta esegue il rendering della versione corrente e le modifiche pubblicate diventano immediatamente visibili, senza ritardi dovuti alla cache.

Gli asset statici in /_next/ e /_jd/ (JavaScript, CSS, font, immagini) vengono serviti con header di cache immutable di lunga durata, quindi Cloudflare li memorizza nella cache all'edge. I nomi dei file contengono un hash del contenuto, quindi ogni build produce nuovi URL e gli asset aggiornati vengono recuperati automaticamente. Non è necessario eseguire il purge.

cacheEverything: true consente a Cloudflare di memorizzare nella cache questi asset statici sulla route proxied; non sovrascrive no-store per l'HTML. Per cancellare manualmente la cache all'edge, usa Purge Cache di Cloudflare (Caching → Configuration → Purge Everything).

La CLI richiede wrangler 3.0 o superiore. Aggiorna con:

npm install -g wrangler@latest

Qual è il prossimo passo?

Solo dominio personalizzato

Impedisci al tuo sottodominio di rispondere direttamente

Domini personalizzati

Verifica il DNS e risolvi i problemi

Hosting su sottopercorso

Servi la documentazione su /docs