AutomationFlowsWeb Scraping › Serve Custom Websites (html Webpages) with Webhooks

Serve Custom Websites (html Webpages) with Webhooks

Original n8n title: 🗲 Serve Custom Websites (html Webpages) with Webhooks

ByLucas Peyrin @lucaspeyrin on n8n.io

This workflow demonstrates how to use n8n to serve a complete, styled HTML webpage. It acts as a mini web server, responding to browser requests with your custom HTML content. Webhook Trigger: The workflow starts with a node configured to listen for requests on a specific path.…

Webhook trigger★★☆☆☆ complexity5 nodes
Web Scraping Trigger: Webhook Nodes: 5 Complexity: ★★☆☆☆ Added:

This workflow corresponds to n8n.io template #5173 — we link there as the canonical source.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "nodes": [
    {
      "id": "2b9d377c-853f-4ef1-92e2-1d4a324179a4",
      "name": "Site",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        100,
        -40
      ],
      "parameters": {
        "options": {
          "responseHeaders": {
            "entries": [
              {
                "name": "Content-Type",
                "value": "text/html; charset=UTF-8"
              }
            ]
          }
        },
        "respondWith": "text",
        "responseBody": "=<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>n8n Workflow: Serving a Static HTML Page</title>\n    <style>\n        :root {\n            --n8n-bg: #131416;\n            --n8n-surface: #1b1c20;\n            --n8n-border: #2a2c31;\n            --n8n-text: #e1e1e1;\n            --n8n-text-muted: #9a9a9a;\n            --n8n-green: #37e2a3;\n            --n8n-purple: #a45fff;\n            --n8n-font: 'Inter', -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n        }\n\n        body {\n            font-family: var(--n8n-font);\n            background-color: var(--n8n-bg);\n            color: var(--n8n-text);\n            margin: 0;\n            padding: 2rem;\n            line-height: 1.6;\n        }\n\n        .container {\n            max-width: 900px;\n            margin: 0 auto;\n        }\n\n        .header {\n            text-align: center;\n            margin-bottom: 3rem;\n        }\n\n        .header h1 {\n            font-size: 2.8rem;\n            font-weight: 700;\n            background: -webkit-linear-gradient(45deg, var(--n8n-green), var(--n8n-purple));\n            -webkit-background-clip: text;\n            -webkit-text-fill-color: transparent;\n            margin-bottom: 0.5rem;\n        }\n\n        .header p {\n            font-size: 1.2rem;\n            color: var(--n8n-text-muted);\n            max-width: 650px;\n            margin: 0 auto;\n        }\n\n        .step {\n            background-color: var(--n8n-surface);\n            border: 1px solid var(--n8n-border);\n            border-radius: 12px;\n            padding: 2rem;\n            margin-bottom: 2rem;\n            display: flex;\n            gap: 2rem;\n            align-items: flex-start;\n        }\n\n        .step-number {\n            flex-shrink: 0;\n            width: 50px;\n            height: 50px;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            border-radius: 50%;\n            background-color: var(--n8n-border);\n            font-size: 1.5rem;\n            font-weight: 600;\n            color: var(--n8n-green);\n        }\n\n        .step-content h2 {\n            margin-top: 0;\n            font-size: 1.5rem;\n            color: var(--n8n-text);\n        }\n\n        .step-content p, .step-content ul {\n            color: var(--n8n-text-muted);\n        }\n        \n        .step-content ul {\n            padding-left: 20px;\n        }\n        \n        .step-content li {\n            margin-bottom: 0.5rem;\n        }\n\n        code {\n            font-family: 'Fira Code', 'Courier New', monospace;\n            background-color: var(--n8n-bg);\n            color: var(--n8n-green);\n            padding: 0.2em 0.4em;\n            border-radius: 4px;\n            font-size: 0.9em;\n        }\n\n        .code-block {\n            background-color: var(--n8n-bg);\n            border: 1px solid var(--n8n-border);\n            border-radius: 8px;\n            padding: 1.5rem;\n            margin-top: 1rem;\n            overflow-x: auto;\n        }\n\n        .code-block pre {\n            margin: 0;\n        }\n        \n        .code-block code {\n            padding: 0;\n            background: none;\n            color: var(--n8n-text-muted);\n        }\n        \n        .code-block .comment {\n            color: #6a6a6a;\n        }\n\n        .final-note {\n            text-align: center;\n            padding: 2rem;\n            background-color: var(--n8n-surface);\n            border: 1px solid var(--n8n-border);\n            border-radius: 12px;\n        }\n        \n        .final-note h2 {\n            color: var(--n8n-green);\n        }\n\n        a {\n            color: var(--n8n-green);\n            text-decoration: none;\n            font-weight: 500;\n        }\n\n        a:hover {\n            text-decoration: underline;\n        }\n\n        @media (max-width: 768px) {\n            body { padding: 1rem; }\n            .header h1 { font-size: 2.2rem; }\n            .step { flex-direction: column; }\n            .step-number { margin-bottom: 1rem; }\n        }\n    </style>\n    <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n    <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n    <link href=\"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Fira+Code&display=swap\" rel=\"stylesheet\">\n</head>\n<body>\n\n    <div class=\"container\">\n\n        <header class=\"header\">\n            <h1>Serve a Full Webpage with n8n</h1>\n            <p>Learn how to use a simple n8n workflow to act as a web server, returning a complete HTML page to anyone who visits your webhook URL.</p>\n        </header>\n\n        <div class=\"step\">\n            <div class=\"step-number\">1</div>\n            <div class=\"step-content\">\n                <h2>The Trigger: Webhook Node</h2>\n                <p>Every workflow that responds to a web request starts with the <strong>Webhook</strong> node. This is your entry point.</p>\n                <ul>\n                    <li>Add a new Webhook node to an empty canvas.</li>\n                    <li>Set the <strong>HTTP Method</strong> to <code>GET</code>. This means it will respond when someone visits the URL in their browser.</li>\n                    <li>Copy the <strong>Production URL</strong>. You'll use this to see your workflow in action. Once you activate the workflow, you'll be able to see your webpage in the browser.</li>\n                </ul>\n            </div>\n        </div>\n\n        <div class=\"step\">\n            <div class=\"step-number\">2</div>\n            <div class=\"step-content\">\n                <h2>The Response: Respond to Webhook Node</h2>\n                <p>This is where the magic happens. This node sends your data back to the browser that triggered the webhook.</p>\n                <p>Connect a <strong>Respond to Webhook</strong> node to your Webhook node. To make it serve a webpage, you need to configure two things:</p>\n                \n                <p><strong>1. Set the Content-Type Header:</strong></p>\n                <p>You must tell the browser it's receiving an HTML document. Under <strong>Options</strong>, add a Response Header:</p>\n                <ul>\n                    <li><strong>Name:</strong> <code>Content-Type</code></li>\n                    <li><strong>Value:</strong> <code>text/html</code></li>\n                </ul>\n\n                <p><strong>2. Add your HTML to the Body:</strong></p>\n                <p>In the <strong>Body</strong> field of the node, paste your entire HTML code. The workflow will send this exact content as the response.</p>\n\n                <div class=\"code-block\">\n                    <pre><code><span class=\"comment\">&lt;!-- Paste your entire HTML file here --&gt;</span>\n&lt;!DOCTYPE html&gt;\n&lt;html lang=\"fr\"&gt;\n&lt;head&gt;\n    &lt;meta charset=\"UTF-8\"&gt;\n    &lt;title&gt;Your Very Own WebPage (AI can build it);/title&gt;\n    &lt;style&gt;\n        :root {\n            --bg-color: #2e2e30;\n            /* ... all your other CSS styles ... */\n        }\n        body {\n            font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto;\n            /* ... etc ... */\n        }\n    &lt;/style&gt;\n&lt;/head&gt;\n&lt;body&gt;\n    &lt;div class=\"container\"&gt;\n        &lt;h1&gt;\ud83d\ude80 Your Very Own WebPage (AI can build it)&lt;/h1&gt;\n        &lt;p&gt;You can put any html here !!&lt;/p&gt;\n        \n        &lt;!-- ... The rest of your HTML content ... --&gt;\n\n    &lt;/div&gt;\n&lt;/body&gt;\n&lt;/html&gt;\n</code></pre>\n                </div>\n            </div>\n        </div>\n\n        <div class=\"final-note\">\n            <h2>That's It!</h2>\n            <p>Activate your workflow. Now, when you visit your <strong>Production URL</strong>, n8n will serve your custom webpage. You've successfully turned a simple workflow into a mini web server.</p>\n            <p>This method is perfect for creating landing pages, dashboards, or dynamic pages where n8n fetches data before rendering the HTML.</p>\n        </div>\n\n    </div>\n\n</body>\n</html>"
      },
      "typeVersion": 1.1
    },
    {
      "id": "ec1325bb-c440-46f2-90e5-3288a0683dda",
      "name": "Your WebPage",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -280,
        -40
      ],
      "parameters": {
        "path": "tutorial/your-webpage",
        "options": {},
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "37f044be-f4b8-4404-bd69-f4f2ce233774",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -400,
        -340
      ],
      "parameters": {
        "color": 6,
        "width": 360,
        "height": 460,
        "content": "### \u25b6\ufe0f START HERE: The Webhook\n\nThis node is the entry point for your webpage.\n\n1.  **Activate** the workflow.\n2.  Copy the **Production URL** from this node.\n3.  Paste the URL into your browser to see the result.\n\n\nThe `Path` is set to `tutorial/your-webpage`, but you can change it to whatever you like."
      },
      "typeVersion": 1
    },
    {
      "id": "6ae79d50-faa3-42d0-ba1d-65de358f0748",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -20,
        -340
      ],
      "parameters": {
        "color": 7,
        "width": 360,
        "height": 460,
        "content": "#### \ud83c\udfa8 CUSTOMIZE YOUR WEBPAGE HERE\n\nThis node sends the HTML content back to the browser.\n\n**To use your own design:**\n1.  **Replace the HTML in the `Body` field** with your own code. You can put anything here: HTML, CSS, and even `<script>` tags.\n2.  Ensure the `Content-Type` header under **Options \u2192 Response Headers** is set to `text/html`. This is crucial for the browser to render the page correctly."
      },
      "typeVersion": 1
    },
    {
      "id": "ba181803-be34-457e-939d-e84d258f2411",
      "name": "Sticky Note12",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        400,
        -340
      ],
      "parameters": {
        "color": 4,
        "width": 540,
        "height": 800,
        "content": "## Was this helpful? Let me know!\n\nI really hope this tutorial helped you understand how to serve a website with a webhook better. Your feedback is incredibly valuable and helps me create better resources for the n8n community.\n\n### **Share Your Thoughts & Ideas**\n\nWhether you have a suggestion, found a typo, or just want to say thanks, I'd love to hear from you!\nHere's a simple n8n form built for this purpose:\n\n#### \u27a1\ufe0f **[Click here to give feedback](https://api.ia2s.app/form/templates/feedback?template=Webhook%20Website%20Tutorial)**\n\n### **Ready to Build Something Great?**\n\nIf you're looking to take your n8n skills or business automation to the next level, I can help.\n\n**\ud83c\udf93 n8n Coaching:** Want to become an n8n pro? I offer one-on-one coaching sessions to help you master workflows, tackle specific problems, and build with confidence.\n#### \u27a1\ufe0f **[Book a Coaching Session](https://api.ia2s.app/form/templates/coaching?template=Webhook%20Website%20Tutorial)**\n\n**\ud83d\udcbc n8n Consulting:** Have a complex project, an integration challenge, or need a custom workflow built for your business? Let's work together to create a powerful automation solution.\n#### \u27a1\ufe0f **[Inquire About Consulting Services](https://api.ia2s.app/form/templates/consulting?template=Webhook%20Website%20Tutorial)**\n\n---\n\nHappy Automating!\nLucas Peyrin"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Your WebPage": {
      "main": [
        [
          {
            "node": "Site",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow demonstrates how to use n8n to serve a complete, styled HTML webpage. It acts as a mini web server, responding to browser requests with your custom HTML content. Webhook Trigger: The workflow starts with a node configured to listen for requests on a specific path.…

Source: https://n8n.io/workflows/5173/ — original creator credit. Request a take-down →

More Web Scraping workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Web Scraping

This template is designed for developers, businesses, and service providers who need to programmatically check Calendly availability. It's perfect for: Web developers building custom booking interface

HTTP Request
Web Scraping

Never lose a prospect to a missed call again. This workflow sends an automatic "sorry we missed you" SMS within seconds, follows up 2 hours later if there's no reply, and enrolls unresponsive contacts

HTTP Request
Web Scraping

Send Postcards to Contacts Automatically using CentralStationCRM and EchtPost. Uses httpRequest. Webhook trigger; 12 nodes.

HTTP Request
Web Scraping

Send Postcards to Contacts Automatically using CentralStationCRM and EchtPost. Uses httpRequest. Webhook trigger; 12 nodes.

HTTP Request
Web Scraping

Send Postcards to Contacts Automatically using CentralStationCRM and EchtPost. Uses httpRequest. Webhook trigger; 12 nodes.

HTTP Request