AutomationFlowsWeb Scraping › Dynamically generate HTML page from user request using OpenAI Structured Output

Dynamically generate HTML page from user request using OpenAI Structured Output

Dynamically generate HTML page from user request using OpenAI Structured Output. Uses respondToWebhook, httpRequest, openAi, html. Webhook trigger; 7 nodes.

Webhook trigger★★☆☆☆ complexityAI-powered7 nodesHttp RequestOpen Ai
Web Scraping Trigger: Webhook Nodes: 7 Complexity: ★★☆☆☆ AI nodes: yes

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
{
  "id": "eXiaTDyKfXpMeyLh",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Dynamically generate HTML page from user request using OpenAI Structured Output",
  "tags": [],
  "nodes": [
    {
      "id": "b1d9659f-4cd0-4f87-844d-32b2af1dcf13",
      "name": "Respond to Webhook",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        2160,
        380
      ],
      "parameters": {
        "options": {
          "responseHeaders": {
            "entries": [
              {
                "name": "Content-Type",
                "value": "text/html; charset=UTF-8"
              }
            ]
          }
        },
        "respondWith": "text",
        "responseBody": "={{ $json.html }}"
      },
      "typeVersion": 1.1
    },
    {
      "id": "5ca8ad3e-7702-4f07-af24-d38e94fdc4ec",
      "name": "Open AI - Using Structured Output",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1240,
        380
      ],
      "parameters": {
        "url": "https://api.openai.com/v1/chat/completions",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"model\": \"gpt-4o-2024-08-06\",\n  \"messages\": [\n    {\n      \"role\": \"system\",\n      \"content\": \"You are a user interface designer and copy writter. Your job is to help users visualize their website ideas. You design elegant and simple webs, with professional text. You use Tailwind framework\"\n    },\n    {\n      \"role\": \"user\",\n      \"content\": \"{{ $json.query.query }}\"\n    }\n  ],\n  \"response_format\":\n{\n  \"type\": \"json_schema\",\n  \"json_schema\": {\n    \"name\": \"ui\",\n    \"description\": \"Dynamically generated UI\",\n    \"strict\": true,\n    \"schema\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"type\": {\n          \"type\": \"string\",\n          \"description\": \"The type of the UI component\",\n          \"enum\": [\n  \"div\",\n  \"span\",\n  \"a\",\n  \"p\",\n  \"h1\",\n  \"h2\",\n  \"h3\",\n  \"h4\",\n  \"h5\",\n  \"h6\",\n  \"ul\",\n  \"ol\",\n  \"li\",\n  \"img\",\n  \"button\",\n  \"input\",\n  \"textarea\",\n  \"select\",\n  \"option\",\n  \"label\",\n  \"form\",\n  \"table\",\n  \"thead\",\n  \"tbody\",\n  \"tr\",\n  \"th\",\n  \"td\",\n  \"nav\",\n  \"header\",\n  \"footer\",\n  \"section\",\n  \"article\",\n  \"aside\",\n  \"main\",\n  \"figure\",\n  \"figcaption\",\n  \"blockquote\",\n  \"q\",\n  \"hr\",\n  \"code\",\n  \"pre\",\n  \"iframe\",\n  \"video\",\n  \"audio\",\n  \"canvas\",\n  \"svg\",\n  \"path\",\n  \"circle\",\n  \"rect\",\n  \"line\",\n  \"polyline\",\n  \"polygon\",\n  \"g\",\n  \"use\",\n  \"symbol\"\n]\n        },\n        \"label\": {\n          \"type\": \"string\",\n          \"description\": \"The label of the UI component, used for buttons or form fields\"\n        },\n        \"children\": {\n          \"type\": \"array\",\n          \"description\": \"Nested UI components\",\n          \"items\": {\n            \"$ref\": \"#\"\n          }\n        },\n        \"attributes\": {\n          \"type\": \"array\",\n          \"description\": \"Arbitrary attributes for the UI component, suitable for any element using Tailwind framework\",\n          \"items\": {\n            \"type\": \"object\",\n            \"properties\": {\n              \"name\": {\n                \"type\": \"string\",\n                \"description\": \"The name of the attribute, for example onClick or className\"\n              },\n              \"value\": {\n                \"type\": \"string\",\n                \"description\": \"The value of the attribute using the Tailwind framework classes\"\n              }\n            },\n            \"additionalProperties\": false,\n            \"required\": [\"name\", \"value\"]\n          }\n        }\n      },\n      \"required\": [\"type\", \"label\", \"children\", \"attributes\"],\n      \"additionalProperties\": false\n    }\n  }\n}\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "nodeCredentialType": "openAiApi"
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "24e5ca73-a3b3-4096-8c66-d84838d89b0c",
      "name": "OpenAI - JSON to HTML",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        1420,
        380
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini",
          "cachedResultName": "GPT-4O-MINI"
        },
        "options": {
          "temperature": 0.2
        },
        "messages": {
          "values": [
            {
              "role": "system",
              "content": "You convert a JSON to HTML. \nThe JSON output has the following fields:\n- html: the page HTML\n- title: the page title"
            },
            {
              "content": "={{ $json.choices[0].message.content }}"
            }
          ]
        },
        "jsonOutput": true
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "c50bdc84-ba59-4f30-acf7-496cee25068d",
      "name": "Format the HTML result",
      "type": "n8n-nodes-base.html",
      "position": [
        1940,
        380
      ],
      "parameters": {
        "html": "<!DOCTYPE html>\n\n<html>\n<head>\n  <meta charset=\"UTF-8\" />\n    <script src=\"https://cdn.tailwindcss.com\"></script>\n  <title>{{ $json.message.content.title }}</title>\n</head>\n<body>\n{{ $json.message.content.html }}\n</body>\n</html>"
      },
      "typeVersion": 1.2
    },
    {
      "id": "193093f4-b1ce-4964-ab10-c3208e343c69",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1134,
        62
      ],
      "parameters": {
        "color": 7,
        "width": 638,
        "height": 503,
        "content": "## Generate HTML from user query\n\n**HTTP Request node**\n- Send the user query to OpenAI, with a defined JSON response format - *using HTTP Request node as it has not yet been implemented in the OpenAI nodes*\n- The response format is inspired by the [Structured Output defined in OpenAI Introduction post](https://openai.com/index/introducing-structured-outputs-in-the-api)\n- The output is a JSON containing HTML components and attributed\n\n\n**OpenAI node**\n- Format the response from the previous node from JSON format to HTML format"
      },
      "typeVersion": 1
    },
    {
      "id": "0371156a-211f-4d92-82b1-f14fe60d4b6b",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        60
      ],
      "parameters": {
        "color": 7,
        "width": 768,
        "height": 503,
        "content": "## Workflow: Dynamically generate an HTML page from a user request using OpenAI Structured Output\n\n**Overview**\n- This workflow is a experiment to build HTML pages from a user input using the new Structured Output from OpenAI.\n- The Structured Output could be used in a variety of cases. Essentially, it guarantees the output from the GPT will follow a defined structure (JSON object).\n- It uses Tailwind CSS to make it slightly nicer, but any\n\n**How it works**\n- Once active, go to the production URL and add what you'd like to build as the parameter \"query\"\n- Example: https://production_url.com?query=a%20signup%20form\n- OpenAI nodes will first output the UI as a JSON then convert it to HTML\n- Finally, the response is integrated in a HTML container and rendered to the user\n\n**Further thoughts**\n- Results are not yet amazing, it is hard to see the direct value of such an experiment\n- But it showcase the potential of the Structured Output. Being able to guarantee the output format is key to build robust AI applications."
      },
      "typeVersion": 1
    },
    {
      "id": "06380781-5189-4d99-9ecd-d8913ce40fd5",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        820,
        380
      ],
      "parameters": {
        "path": "d962c916-6369-431a-9d80-af6e6a50fdf5",
        "options": {
          "allowedOrigins": "*"
        },
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    }
  ],
  "active": true,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "d2307a2a-5427-4769-94a6-10eab703a788",
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "Open AI - Using Structured Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI - JSON to HTML": {
      "main": [
        [
          {
            "node": "Format the HTML result",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format the HTML result": {
      "main": [
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Open AI - Using Structured Output": {
      "main": [
        [
          {
            "node": "OpenAI - JSON to HTML",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

About this workflow

Dynamically generate HTML page from user request using OpenAI Structured Output. Uses respondToWebhook, httpRequest, openAi, html. Webhook trigger; 7 nodes.

Source: https://github.com/Zie619/n8n-workflows — original creator credit. Request a take-down →

More Web Scraping workflows → · Browse all categories →