Dynamically generate a webpage from user request using OpenAI Structured Output https://n8nworkflows.xyz/workflows/dynamically-generate-a-webpage-from-user-request-using-openai-structured-output-2388 # Dynamically generate a webpage from user request using OpenAI Structured Output ### 1. Workflow Overview This workflow dynamically generates an HTML webpage based on a user’s query parameter by leveraging OpenAI’s Structured Output feature. Users specify what kind of page they want (e.g., a signup form) via a URL query parameter. The workflow then: - Receives the user request through a webhook (1.1 Input Reception). - Sends the query to OpenAI’s GPT model using a structured JSON schema to ensure the output follows a predefined UI component format (1.2 Structured UI Generation). - Converts the structured JSON UI description into HTML using OpenAI’s language model (1.3 JSON-to-HTML Transformation). - Wraps the generated HTML inside a full HTML document including Tailwind CSS for styling (1.4 HTML Formatting). - Returns the fully formed HTML page as a response to the webhook (1.5 Webhook Response). **Logical Blocks:** - **1.1 Input Reception:** Webhook node receives user HTTP requests with query parameter. - **1.2 Structured UI Generation:** HTTP Request node calls OpenAI API with a JSON schema prompt to generate UI components. - **1.3 JSON-to-HTML Transformation:** OpenAI node converts JSON UI structure to HTML markup. - **1.4 HTML Formatting:** HTML node wraps the HTML snippet with proper document structure and Tailwind CSS. - **1.5 Webhook Response:** Respond To Webhook node sends the final HTML page back to the user. --- ### 2. Block-by-Block Analysis --- #### 1.1 Input Reception **Overview:** Receives HTTP requests with a query parameter specifying the desired webpage content. This is the entry point of the workflow. **Nodes Involved:** - Webhook **Node Details:** - **Webhook** - Type: Webhook (n8n-nodes-base.webhook) - Configuration: - Path: Unique webhook path (`d962c916-6369-431a-9d80-af6e6a50fdf5`) - Allowed Origins: All (`*`) for CORS flexibility - Response Mode: `responseNode` to delegate response to a later node - Input: External HTTP requests with URL query parameters, expects `query` parameter - Output: Passes received data forward, including the raw query string under `$json.query.query` - Failures: Invalid or missing query parameter will cause downstream nodes to fail or produce empty results. No explicit validation here. - Version: 2 (Webhook node version) --- #### 1.2 Structured UI Generation **Overview:** Sends the user query to OpenAI’s chat completions endpoint using a structured JSON schema as the response format to generate a UI definition in JSON. **Nodes Involved:** - Open AI - Using Structured Output (HTTP Request) **Node Details:** - **Open AI - Using Structured Output** - Type: HTTP Request (n8n-nodes-base.httpRequest) - Configuration: - URL: `https://api.openai.com/v1/chat/completions` - Method: POST - Body Type: JSON with the following payload structure: - Model: `gpt-4o-2024-08-06` (latest GPT-4 variant supporting structured output) - Messages: - System role: Defines assistant as a UI designer and copywriter using Tailwind CSS - User role: Injects the user query string dynamically (`{{ $json.query.query }}`) - Response Format: JSON schema defining allowed UI components and their properties (strict validation) - The schema enumerates HTML element types (e.g., div, span, input, form, button, etc.) - Each component includes `type`, `label`, `children` (recursive), and `attributes` (name-value pairs for Tailwind classes or events) - Headers: Content-Type application/json - Authentication: OpenAI API Key via predefined credential - Input: Receives webhook data containing the `query` string - Output: JSON structured UI definition in the response body (OpenAI chat completion) - Potential Failures: - Authentication errors with OpenAI API key - Rate limiting or API timeouts - Schema validation errors if prompt or model output doesn’t conform - Version: 4.2 (HTTP Request node) - Sticky Note attached explaining this node’s special role and usage of HTTP Request node due to missing native OpenAI structured output support --- #### 1.3 JSON-to-HTML Transformation **Overview:** Transforms the JSON UI structure generated by the previous node into HTML markup using an OpenAI model specialized for this conversion. **Nodes Involved:** - OpenAI - JSON to HTML **Node Details:** - **OpenAI - JSON to HTML** - Type: OpenAI (Langchain) Node (`@n8n/n8n-nodes-langchain.openAi`) - Configuration: - Model: `gpt-4o-mini` (smaller GPT-4 variant for faster response) - Temperature: 0.2 (low randomness for consistent output) - Messages: - System message instructs the AI to convert JSON fields `html` and `title` into HTML output - User message contains the JSON UI definition extracted from previous node's output (`{{ $json.choices[0].message.content }}`) - Output: JSON expected output (`jsonOutput` set to true), containing at least `html` and `title` fields - Input: JSON UI structure from previous OpenAI HTTP Request node - Output: JSON containing the HTML snippet and page title - Potential Failures: - Parsing errors if input JSON is malformed - API errors or timeouts - Inconsistent HTML generation if input is unexpected - Version: 1.3 --- #### 1.4 HTML Formatting **Overview:** Wraps the generated HTML snippet and title into a complete HTML document including standard document structure and Tailwind CSS integration. **Nodes Involved:** - Format the HTML result (HTML Node) **Node Details:** - **Format the HTML result** - Type: HTML (n8n-nodes-base.html) - Configuration: - HTML Template: ```html {{ $json.message.content.title }} {{ $json.message.content.html }} ``` - Uses expressions to insert `title` and `html` fields dynamically from the previous node output - Input: JSON with fields `message.content.title` and `message.content.html` from OpenAI JSON-to-HTML node - Output: Complete HTML document as a string - Potential Failures: - Missing or malformed fields in input JSON - Expression evaluation errors - Version: 1.2 --- #### 1.5 Webhook Response **Overview:** Sends the final generated HTML page back to the user as the HTTP response with appropriate content-type headers. **Nodes Involved:** - Respond to Webhook **Node Details:** - **Respond to Webhook** - Type: Respond to Webhook (n8n-nodes-base.respondToWebhook) - Configuration: - Response Body: Sends the formatted HTML from the previous node (`={{ $json.html }}`) - Response Headers: Sets `Content-Type` to `text/html; charset=UTF-8` to render as a webpage - Input: HTML document string from the "Format the HTML result" node - Output: HTTP response to the original webhook request - Potential Failures: - If input is empty or malformed, browser may display errors or blank page - Version: 1.1 --- ### 3. Summary Table | Node Name | Node Type | Functional Role | Input Node(s) | Output Node(s) | Sticky Note | |-----------------------------|-------------------------------|----------------------------------------------|---------------------------------|------------------------------|------------------------------------------------------------------------------------------------------------------------------------------| | Webhook | Webhook (n8n-nodes-base.webhook) | Receives user HTTP requests with query param | None | Open AI - Using Structured Output | | | Open AI - Using Structured Output | HTTP Request (n8n-nodes-base.httpRequest) | Sends user query to OpenAI with JSON schema | Webhook | OpenAI - JSON to HTML | Explains use of HTTP Request node for Structured Output and JSON response format, inspired by OpenAI structured outputs introduction. | | OpenAI - JSON to HTML | OpenAI Langchain Node | Converts JSON UI structure to HTML | Open AI - Using Structured Output | Format the HTML result | | | Format the HTML result | HTML (n8n-nodes-base.html) | Wraps HTML snippet in full HTML doc with Tailwind CSS | OpenAI - JSON to HTML | Respond to Webhook | | | Respond to Webhook | Respond to Webhook (n8n-nodes-base.respondToWebhook) | Sends final HTML page as HTTP response | Format the HTML result | None | | | Sticky Note | Sticky Note | Documentation and explanation | None | None | Explains the workflow concept and user instructions including example usage and general thoughts on structured output utility. | | Sticky Note1 | Sticky Note | Documentation and explanation | None | None | Overview of workflow purpose and how it works; notes on Tailwind CSS and structured output benefits, with example URL usage instructions. | --- ### 4. Reproducing the Workflow from Scratch 1. **Create Webhook Node** - Type: Webhook - Parameters: - Path: Set a unique webhook identifier (e.g., `d962c916-6369-431a-9d80-af6e6a50fdf5`) - Allowed Origins: `*` - Response Mode: `responseNode` (to delegate response) - This node will receive HTTP requests containing the `query` parameter. 2. **Create HTTP Request Node for Structured Output** - Name: Open AI - Using Structured Output - Type: HTTP Request - Parameters: - URL: `https://api.openai.com/v1/chat/completions` - Method: POST - Authentication: Select or create OpenAI API credentials (OpenAI API key) - Headers: Content-Type: application/json - Body Content (JSON): ```json { "model": "gpt-4o-2024-08-06", "messages": [ { "role": "system", "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" }, { "role": "user", "content": "{{ $json.query.query }}" } ], "response_format": { "type": "json_schema", "json_schema": { "name": "ui", "description": "Dynamically generated UI", "strict": true, "schema": { "type": "object", "properties": { "type": { "type": "string", "description": "The type of the UI component", "enum": [ "div", "span", "a", "p", "h1", "h2", "h3", "h4", "h5", "h6", "ul", "ol", "li", "img", "button", "input", "textarea", "select", "option", "label", "form", "table", "thead", "tbody", "tr", "th", "td", "nav", "header", "footer", "section", "article", "aside", "main", "figure", "figcaption", "blockquote", "q", "hr", "code", "pre", "iframe", "video", "audio", "canvas", "svg", "path", "circle", "rect", "line", "polyline", "polygon", "g", "use", "symbol" ] }, "label": { "type": "string", "description": "The label of the UI component, used for buttons or form fields" }, "children": { "type": "array", "description": "Nested UI components", "items": { "$ref": "#" } }, "attributes": { "type": "array", "description": "Arbitrary attributes for the UI component, suitable for any element using Tailwind framework", "items": { "type": "object", "properties": { "name": { "type": "string" }, "value": { "type": "string" } }, "required": ["name", "value"], "additionalProperties": false } } }, "required": ["type", "label", "children", "attributes"], "additionalProperties": false } } } } ``` - Enable "Send Body" and "Send Headers" - Connect Webhook node output to this HTTP Request node input. 3. **Create OpenAI Node for JSON-to-HTML Conversion** - Name: OpenAI - JSON to HTML - Type: OpenAI (Langchain) Node - Parameters: - Model ID: `gpt-4o-mini` - Temperature: 0.2 - Messages: - System role content: ``` You convert a JSON to HTML. The JSON output has the following fields: - html: the page HTML - title: the page title ``` - User role content: `={{ $json.choices[0].message.content }}` (maps the JSON UI structure from previous node) - Enable JSON output option - Credentials: Use the same OpenAI API key credential - Connect the HTTP Request node output to this OpenAI node input. 4. **Create HTML Node to Format Complete HTML Document** - Name: Format the HTML result - Type: HTML - Parameters: - HTML Content: ```html {{ $json.message.content.title }} {{ $json.message.content.html }} ``` - Connect OpenAI JSON-to-HTML node output to this HTML node input. 5. **Create Respond to Webhook Node** - Name: Respond to Webhook - Type: Respond to Webhook - Parameters: - Respond With: Text - Response Body: `={{ $json.html }}` (injects the full HTML document) - Response Headers: Add entry with Name `Content-Type` and Value `text/html; charset=UTF-8` - Connect the HTML node output to this Respond to Webhook node input. 6. **Activate the workflow.** 7. **Usage:** - Call the webhook URL with a query parameter `query` describing the desired page, e.g.: `https:///?query=a signup form` - The workflow generates and returns a fully formed HTML page. --- ### 5. General Notes & Resources | Note Content | Context or Link | |---------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------| | This workflow is a proof of concept demonstrating OpenAI’s Structured Output feature to generate UI components | OpenAI Structured Outputs Intro: https://openai.com/index/introducing-structured-outputs-in-the-api | | Tailwind CSS is embedded via CDN script tag to style generated pages effortlessly | https://tailwindcss.com | | OpenAI API Key creation required for credentials setup | https://platform.openai.com/api-keys | | Example query usage: `?query=a signup form` to generate a signup form webpage | Highlighted in workflow description | | The workflow uses HTTP Request node for Structured Output as official OpenAI node does not yet support it | Sticky note on the HTTP Request node explains this design choice | | Results currently are experimental and may need prompt tuning for production readiness | Workflow sticky notes mention limitations and thoughts on structured output robustness | --- This comprehensive documentation enables users and developers to fully understand, reproduce, and extend the workflow with confidence.