AutomationFlowsWeb Scraping › Collect Star Rating Feedback with Self-contained HTML Forms and Data Tables

Collect Star Rating Feedback with Self-contained HTML Forms and Data Tables

ByAlexander Schnabl @alexschnabl on n8n.io

This n8n template lets you collect lightweight customer feedback through a responsive HTML form with a mandatory 1–5 star rating and an optional message. Submissions are stored in an n8n Data Table (including any query-string context like or ) and the user is redirected to a…

Webhook trigger★★★★☆ complexity15 nodesData Table
Web Scraping Trigger: Webhook Nodes: 15 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #9787 — 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
{
  "id": "VDut3fLvTiutz3bF",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Customer Feedback Collector",
  "tags": [],
  "nodes": [
    {
      "id": "e12b4e8b-25e7-4650-8421-3b31bd39260b",
      "name": "Feedback Input HTML",
      "type": "n8n-nodes-base.html",
      "position": [
        352,
        0
      ],
      "parameters": {
        "html": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"utf-8\" />\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n  <title>{{ $('Form Configuration').item.json.Title }}</title>\n  <style>\n    :root {\n      --bg: {{ $json.bg }};\n      --card: {{ $json.card }};\n      --text: {{ $json.text }};\n      --muted: {{ $json.muted }};\n      --accent: {{ $json.accent }};\n      --accent-contrast: {{ $json[\"accent-contrast\"] }};\n      --border: {{ $json.border }};\n      --star: {{ $json.star }};\n      --star-active: {{ $json[\"star-active\"] }};\n      --focus: {{ $json.focus }};\n      --radius: {{ $json.radius }};\n      --shadow: {{ $json.shadow }};\n      --maxw: {{ $json.maxw }};\n      --star-size: {{ $json[\"star-size\"] }};\n    }\n\n    * { box-sizing: border-box; }\n    html, body { height: 100%; }\n    body {\n      margin: 0;\n      font: 16px/1.5 system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, Helvetica, Arial, \"Apple Color Emoji\", \"Segoe UI Emoji\";\n      background: var(--bg);\n      color: var(--text);\n      display: grid;\n      place-items: center;\n      padding: 24px;\n    }\n\n    .card {\n      width: 100%;\n      max-width: var(--maxw);\n      background: var(--card);\n      border: 1px solid var(--border);\n      border-radius: var(--radius);\n      box-shadow: var(--shadow);\n      padding: 24px;\n    }\n\n    h1 { font-size: 1.25rem; margin: 0 0 4px; }\n    .sub { color: var(--muted); margin: 0 0 18px; font-size: 0.95rem; }\n\n    form { display: grid; gap: 18px; }\n    .field { display: grid; gap: 10px; }\n    label.top { font-weight: 600; }\n\n    .stars {\n      display: flex;\n      flex-direction: row-reverse;\n      justify-content: flex-end;\n      gap: 6px;\n    }\n\n    .stars input {\n      position: absolute;\n      inline-size: 1px;\n      block-size: 1px;\n      margin: -1px;\n      padding: 0;\n      border: 0;\n      clip: rect(0 0 0 0);\n      clip-path: inset(50%);\n      overflow: hidden;\n      white-space: nowrap;\n    }\n\n    .stars label {\n      cursor: pointer;\n      font-size: var(--star-size);\n      line-height: 1;\n      filter: drop-shadow(0 1px 0 rgba(0,0,0,0.05));\n    }\n\n    .stars label span { color: var(--star); transition: color 150ms ease; }\n    .stars label:hover span,\n    .stars label:hover ~ label span { color: var(--star-active); }\n    .stars input:checked ~ label span { color: var(--star-active); }\n\n    textarea {\n      width: 100%;\n      min-height: 110px;\n      resize: vertical;\n      padding: 12px 14px;\n      border-radius: 12px;\n      border: 1px solid var(--border);\n      background: #fff;\n      color: var(--text);\n      font: inherit;\n    }\n\n    textarea:focus { outline: none; box-shadow: var(--focus); border-color: var(--accent); }\n\n    .actions { display: flex; gap: 12px; justify-content: flex-end; }\n\n    button {\n      appearance: none;\n      border: 1px solid var(--accent);\n      background: var(--accent);\n      color: var(--accent-contrast);\n      padding: 10px 16px;\n      border-radius: 12px;\n      font-weight: 600;\n      cursor: pointer;\n      box-shadow: 0 6px 16px rgba(59, 130, 246, 0.25);\n    }\n\n    .muted-btn { background: transparent; color: var(--text); border-color: var(--border); box-shadow: none; }\n  </style>\n</head>\n<body>\n  <main class=\"card\" aria-labelledby=\"title\">\n    <h1 id=\"title\">{{ $('Form Configuration').item.json.Header }}</h1>\n    <p class=\"sub\">{{ $('Form Configuration').item.json.Description }}</p>\n\n    <form action=\"{{ $('Form Configuration').item.json.PostFeedbackLink }}{{ $('Form Configuration').item.json.queryParams }}\" method=\"POST\">\n      <div class=\"field\">\n        <label class=\"top\" for=\"rating-1\">Star rating <span aria-hidden=\"true\">*</span></label>\n        <div class=\"stars\" role=\"radiogroup\" aria-label=\"Star rating from 1 to 5\">\n          <input type=\"radio\" name=\"rating\" id=\"rating-5\" value=\"5\" required>\n          <label for=\"rating-5\" title=\"5 stars\"><span>\u2605</span></label>\n\n          <input type=\"radio\" name=\"rating\" id=\"rating-4\" value=\"4\" required>\n          <label for=\"rating-4\" title=\"4 stars\"><span>\u2605</span></label>\n\n          <input type=\"radio\" name=\"rating\" id=\"rating-3\" value=\"3\" required>\n          <label for=\"rating-3\" title=\"3 stars\"><span>\u2605</span></label>\n\n          <input type=\"radio\" name=\"rating\" id=\"rating-2\" value=\"2\" required>\n          <label for=\"rating-2\" title=\"2 stars\"><span>\u2605</span></label>\n\n          <input type=\"radio\" name=\"rating\" id=\"rating-1\" value=\"1\" required>\n          <label for=\"rating-1\" title=\"1 star\"><span>\u2605</span></label>\n        </div>\n      </div>\n\n      <div class=\"field\">\n        <label class=\"top\" for=\"message\">Message (optional)</label>\n        <textarea id=\"message\" name=\"message\" placeholder=\"Tell us a bit more\u2026\"></textarea>\n      </div>\n\n      <div class=\"actions\">\n        <button type=\"reset\" class=\"muted-btn\">{{ $('Form Configuration').item.json.ClearBtn }}</button>\n        <button type=\"submit\">{{ $('Form Configuration').item.json.SubmitBtn }}</button>\n      </div>\n    </form>\n  </main>\n</body>\n</html>"
      },
      "typeVersion": 1.2
    },
    {
      "id": "3cb73422-b12a-4afe-a76f-d935ad253497",
      "name": "Form Configuration",
      "type": "n8n-nodes-base.set",
      "position": [
        -96,
        0
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "eb90800e-3fba-4f93-9058-3b663d6d92b1",
              "name": "Title",
              "type": "string",
              "value": "Simple Feedback Input"
            },
            {
              "id": "9b12be64-eca5-46b0-be34-a2760c03d356",
              "name": "Header",
              "type": "string",
              "value": "Rate your experience"
            },
            {
              "id": "230249b4-6431-455c-94fa-640720e4eb77",
              "name": "Description",
              "type": "string",
              "value": "Your rating helps us improve. Stars are required; message is optional."
            },
            {
              "id": "5c4f7ad0-b1dd-4eb5-9795-42b1051fa57e",
              "name": "ClearBtn",
              "type": "string",
              "value": "Clear"
            },
            {
              "id": "be71a869-305f-4039-a5aa-1d6f03fc50db",
              "name": "SubmitBtn",
              "type": "string",
              "value": "Submit feedback"
            },
            {
              "id": "d5b8e79b-fd2c-4cc5-9885-7259ee700477",
              "name": "PostFeedbackLink",
              "type": "string",
              "value": "https://sus-tech.app.n8n.cloud/webhook-test/feedback"
            },
            {
              "id": "4da8b6ef-efac-40d3-bdae-d06215fea967",
              "name": "queryParams",
              "type": "string",
              "value": "={{ $json.query && Object.keys($json.query).length\n  ? '?' + Object.keys($json.query)\n      .filter(k => $json.query[k] !== undefined && $json.query[k] !== null && $json.query[k] !== '')\n      .map(k => encodeURIComponent(k) + '=' + encodeURIComponent(String($json.query[k])))\n      .join('&')\n  : ''\n}}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "cf34fc30-a548-41a5-a408-2d2bc12a3d86",
      "name": "Post Feedback",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -320,
        224
      ],
      "parameters": {
        "path": "feedback",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2.1
    },
    {
      "id": "e84bbcd8-da2c-48ba-b35b-2e46a3482a0f",
      "name": "Input Feedback",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -320,
        0
      ],
      "parameters": {
        "path": "feedback",
        "options": {},
        "responseMode": "responseNode"
      },
      "typeVersion": 2.1
    },
    {
      "id": "8cc22ea0-5c45-49cf-89c2-a1b4127db156",
      "name": "Page Configuration",
      "type": "n8n-nodes-base.set",
      "position": [
        128,
        224
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "40ca52c0-1258-4e59-aaa8-dd933d165c88",
              "name": "Title",
              "type": "string",
              "value": "Thank You for Your Feedback"
            },
            {
              "id": "94332494-7637-4df4-9281-e31fec3972ff",
              "name": "Header",
              "type": "string",
              "value": "Thank You!"
            },
            {
              "id": "82d691be-165a-44ef-be1b-8139e5a08eba",
              "name": "Description",
              "type": "string",
              "value": "We appreciate your feedback \u2014 it helps us improve our service."
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "df3617bd-2f2d-4710-a5c6-2dde47088291",
      "name": "Theme Configuration - Feedback Input",
      "type": "n8n-nodes-base.set",
      "position": [
        128,
        0
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "{\n  \"bg\": \"#f7f8fb\",\n  \"card\": \"#ffffff\",\n  \"text\": \"#1f2937\",\n  \"muted\": \"#6b7280\",\n  \"accent\": \"#3b82f6\",\n  \"accent-contrast\": \"#ffffff\",\n  \"border\": \"#e5e7eb\",\n  \"star\": \"#cbd5e1\",\n  \"star-active\": \"#f59e0b\",\n  \"focus\": \"0 0 0 4px rgba(59, 130, 246, 0.25)\",\n  \"radius\": \"16px\",\n  \"shadow\": \"0 10px 25px rgba(2, 6, 23, 0.06), 0 4px 10px rgba(2, 6, 23, 0.04)\",\n  \"maxw\": \"560px\",\n  \"star-size\": \"28px\"\n}"
      },
      "typeVersion": 3.4
    },
    {
      "id": "478081b7-dda8-4963-a388-b38a0c289000",
      "name": "Feedback Submitted HTML",
      "type": "n8n-nodes-base.html",
      "position": [
        576,
        224
      ],
      "parameters": {
        "html": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"utf-8\" />\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n  <title>Thank You for Your Feedback</title>\n  <style>\n    :root {\n      --bg: #f7f8fb;\n      --card: #ffffff;\n      --muted: #6b7280;\n      --border: #e5e7eb;\n      --radius: 16px;\n      --shadow: 0 10px 25px rgba(2, 6, 23, 0.06), 0 4px 10px rgba(2, 6, 23, 0.04);\n      --maxw: 560px;\n    }\n\n    * { box-sizing: border-box; }\n    html, body { height: 100%; }\n\n    body {\n      margin: 0;\n      font: 16px/1.5 system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, Helvetica, Arial;\n      background: var(--bg);\n      color: var(--text);\n      display: grid;\n      place-items: center;\n      padding: 24px;\n    }\n\n    .card {\n      width: 100%;\n      max-width: var(--maxw);\n      background: var(--card);\n      border: 1px solid var(--border);\n      border-radius: var(--radius);\n      box-shadow: var(--shadow);\n      padding: 40px 28px;\n      text-align: center;\n    }\n\n    h1 {\n      font-size: 1.6rem;\n    }\n\n    p.sub {\n      color: var(--muted);\n      font-size: 1rem;\n    }\n  </style>\n</head>\n<body>\n  <main class=\"card\">\n    <h1>Thank You!</h1>\n    <p class=\"sub\">We appreciate your feedback \u2014 it helps us improve our service.</p>\n  </main>\n</body>\n</html>"
      },
      "typeVersion": 1.2
    },
    {
      "id": "adf15b9a-be26-4db1-8d95-052b557e69d8",
      "name": "Theme Configuration - Feedback Submitted",
      "type": "n8n-nodes-base.set",
      "position": [
        352,
        224
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "{\n  \"bg\": \"#f7f8fb\",\n  \"card\": \"#ffffff\",\n  \"muted\": \"#6b7280\",\n  \"border\": \"#e5e7eb\",\n  \"radius\": \"16px\",\n  \"shadow\": \"0 10px 25px rgba(2, 6, 23, 0.06), 0 4px 10px rgba(2, 6, 23, 0.04)\",\n  \"maxw\": \"560px\"\n}"
      },
      "typeVersion": 3.4
    },
    {
      "id": "5d455df8-2475-4d9e-a3d4-910b71b7e426",
      "name": "Respond with Feedback Submitted",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        800,
        224
      ],
      "parameters": {
        "options": {},
        "respondWith": "text",
        "responseBody": "={{ $json.html }}"
      },
      "typeVersion": 1.4
    },
    {
      "id": "721dbba9-5668-481c-b775-3c0af3e0a905",
      "name": "Respond with Feedback Input",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        576,
        0
      ],
      "parameters": {
        "options": {},
        "respondWith": "text",
        "responseBody": "={{ $json.html }}"
      },
      "typeVersion": 1.4
    },
    {
      "id": "6217311f-fe16-4240-a8c2-69708c26641b",
      "name": "Save Feedback to Data Table",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        -96,
        224
      ],
      "parameters": {
        "columns": {
          "value": {
            "rating": "={{ $json.body.rating }}",
            "message": "={{ $json.body.message }}",
            "additionalInformation": "={{ JSON.stringify($json.query) }}"
          },
          "schema": [
            {
              "id": "rating",
              "type": "number",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "rating",
              "defaultMatch": false
            },
            {
              "id": "message",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "message",
              "defaultMatch": false
            },
            {
              "id": "additionalInformation",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "additionalInformation",
              "defaultMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "0wPZ9d7FiU9fblye",
          "cachedResultUrl": "/projects/YLDgXBJO8HihYrEM/datatables/0wPZ9d7FiU9fblye",
          "cachedResultName": "Feedback"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "d814b58f-c0e4-436f-a3d6-e86b072c3607",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -848,
        -176
      ],
      "parameters": {
        "color": 4,
        "width": 480,
        "content": "### Overview\n- Collects quick **1\u20135\u2b50 feedback** + optional message.  \n- Saves results to an **n8n Data Table**, including any query params.  \n- Displays a simple **\u201cThank you\u201d** confirmation page.  \n- Fully self-contained \u2014 **no external services or creds** needed."
      },
      "typeVersion": 1
    },
    {
      "id": "64b43e7f-8f92-4ba7-acef-c0fd2b2bea1a",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -352,
        -176
      ],
      "parameters": {
        "color": 5,
        "width": 672,
        "content": "### Setup\n* Open **Form Configuration** \u2192 update title, text, and `PostFeedbackLink` (the POST Feedback webhook URL).  \n* Optionally adjust **Theme Configuration**\n* Confirm **Data Table** mapping (rating, message, additional info).  "
      },
      "typeVersion": 1
    },
    {
      "id": "bedfbab0-58d1-4371-aeba-6e724e58b3db",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -848,
        0
      ],
      "parameters": {
        "width": 480,
        "content": "### How It Works\n- **GET `/feedback`** \u2192 renders the styled HTML form.  \n- **POST `/feedback`** \u2192 receives rating/message, saves to Data Table, returns confirmation.  \n- Query params (e.g. `?userId=123&source=email`) are automatically stored as JSON.  "
      },
      "typeVersion": 1
    },
    {
      "id": "f4c0fb33-498f-4b00-a901-bed5794604f0",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -848,
        176
      ],
      "parameters": {
        "color": 6,
        "width": 480,
        "height": 192,
        "content": "### Notes\n- Only submitted fields + query info are stored. \n- If something fails:  \n  - Ensure both webhooks are published. \n  - Verify the `PostFeedbackLink`\n  - Check Data Table schema matches node mapping.  \n- Need help? \u2709\ufe0f **office@sus-tech.at**"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "f40e8a7d-45dc-4054-aaa6-8ce99afff84b",
  "connections": {
    "Post Feedback": {
      "main": [
        [
          {
            "node": "Save Feedback to Data Table",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Input Feedback": {
      "main": [
        [
          {
            "node": "Form Configuration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Form Configuration": {
      "main": [
        [
          {
            "node": "Theme Configuration - Feedback Input",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Page Configuration": {
      "main": [
        [
          {
            "node": "Theme Configuration - Feedback Submitted",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Feedback Input HTML": {
      "main": [
        [
          {
            "node": "Respond with Feedback Input",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Feedback Submitted HTML": {
      "main": [
        [
          {
            "node": "Respond with Feedback Submitted",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save Feedback to Data Table": {
      "main": [
        [
          {
            "node": "Page Configuration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Theme Configuration - Feedback Input": {
      "main": [
        [
          {
            "node": "Feedback Input HTML",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Theme Configuration - Feedback Submitted": {
      "main": [
        [
          {
            "node": "Feedback Submitted HTML",
            "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 n8n template lets you collect lightweight customer feedback through a responsive HTML form with a mandatory 1–5 star rating and an optional message. Submissions are stored in an n8n Data Table (including any query-string context like or ) and the user is redirected to a…

Source: https://n8n.io/workflows/9787/ — 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

Response_Handler. Uses httpRequest, dataTable, n8n-nodes-evolution-api, redis. Webhook trigger; 32 nodes.

HTTP Request, Data Table, N8N Nodes Evolution Api +1
Web Scraping

Receive instant push notifications on your phone and voice announcements on your Google Home every time someone orders from your intranet menu — with cumulative BAC tracking per person.

Data Table, HTTP Request, Home Assistant
Web Scraping

This n8n template provides enterprise-level version control for your workflows using GitHub integration. Stop losing hours to broken workflows and manual exports – get proper commit history, visual di

n8n, Execute Workflow Trigger, HTTP Request +1
Web Scraping

This flow creates dummy files for every item added in your *Arrs (Radarr/Sonarr) with the tag .

HTTP Request, Ssh
Web Scraping

This workflow acts as a central API gateway for all technical indicator agents in the Binance Spot Market Quant AI system. It listens for incoming webhook requests and dynamically routes them to the c

HTTP Request