AutomationFlowsData & Sheets › Automate Woocommerce SEO with Yoast & Ai-powered Meta Tag Generation for Free

Automate Woocommerce SEO with Yoast & Ai-powered Meta Tag Generation for Free

ByDavide Boizza @n3witalia on n8n.io

This workflow is designed to automate the generation and updating of SEO meta titles and descriptions for WooCommerce products using n8n. It leverages Google Sheets for data input, a FREE language model (Gemini 2.0 Flash Exp. via OpenRouter) for generating SEO-optimized meta…

Event trigger★★★★☆ complexityAI-powered14 nodesOutput Parser StructuredGoogle SheetsWooCommerceChain LlmOpenRouter Chat
Data & Sheets Trigger: Event Nodes: 14 Complexity: ★★★★☆ AI nodes: yes Added:

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

This workflow follows the Chainllm → Google Sheets recipe pattern — see all workflows that pair these two integrations.

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": "JCp6tMYrzFDSOQ1C",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "WooCommerce SEO Yoast Meta Tag Generation",
  "tags": [],
  "nodes": [
    {
      "id": "02c4abf8-64f5-45e5-934f-0f1db4484c78",
      "name": "When clicking \u2018Test workflow\u2019",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        120,
        -480
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "d545f0e0-76dd-490b-85b6-7a83b65eb8f6",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        920,
        -280
      ],
      "parameters": {
        "schemaType": "manual",
        "inputSchema": "{\n\t\"type\": \"object\",\n\t\"properties\": {\n\t\t\"metatitle\": {\n\t\t\t\"type\": \"string\"\n\t\t},\n\t\t\"metadescription\": {\n\t\t\t\"type\": \"string\"\n\t\t}\n\t}\n}"
      },
      "typeVersion": 1.2
    },
    {
      "id": "a9873f0e-8325-4434-9219-45c711a7afad",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        120,
        -660
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "minutes"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "9a232d7e-97e7-4e47-85ab-5069108d53ab",
      "name": "Get product ID",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        320,
        -480
      ],
      "parameters": {
        "options": {
          "returnFirstMatch": true
        },
        "filtersUI": {
          "values": [
            {
              "lookupColumn": "METATITLE"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17eYoKhtUupkye9Bmv13BjfP2jyymBUW4UYQGWU6V2cs/edit#gid=0",
          "cachedResultName": "Foglio1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "17eYoKhtUupkye9Bmv13BjfP2jyymBUW4UYQGWU6V2cs",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17eYoKhtUupkye9Bmv13BjfP2jyymBUW4UYQGWU6V2cs/edit?usp=drivesdk",
          "cachedResultName": "Metatitle and Metadescription WooCommerce"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "b4324a6a-7c53-460e-9966-37a8df4d0ae9",
      "name": "Get product",
      "type": "n8n-nodes-base.wooCommerce",
      "position": [
        520,
        -480
      ],
      "parameters": {
        "operation": "get",
        "productId": "={{ $json['ID POST'] }}"
      },
      "credentials": {
        "wooCommerceApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "28a911b7-0d74-4686-a349-f727b0ee9641",
      "name": "Generate metatitle e metadescription",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        740,
        -480
      ],
      "parameters": {
        "text": "=Create metatitle and metadescription in the language of the following product:\n- Title: {{ $json.name }}\n- Description: {{ $json.description }}\n- Short description: {{ $json.short_description }}\n- Product category: {{ (JSON.stringify($json.categories)) }},",
        "messages": {
          "messageValues": [
            {
              "message": "=You are a SEO expert specialized in creating optimized meta tags. Your task is to analyze the provided content and generate:\n\n1. A meta title of maximum 60 characters that:\n   - Includes the main keyword in a strategic position\n   - Is engaging and encourages clicks\n   - Accurately reflects the page content\n   - Uses clear and direct language\n   - Avoids keyword stuffing\n\n2. A meta description of maximum 160 characters that:\n   - Provides an engaging summary of the content\n   - Includes an appropriate call-to-action\n   - Contains the main keyword and relevant variations\n   - Is grammatically correct and flows well\n   - Maintains consistency with the meta title\n\nANALYSIS PROCESS:\n1. Carefully read the provided content\n2. Identify:\n   - Main topic\n   - Primary and related keywords\n   - Search intent\n   - Unique selling proposition\n   - Target audience\n\n3. Formulate meta tags that:\n   - Maximize CTR\n   - Respect character limits\n   - Are SEO optimized\n   - Reflect the content\n   - Don't insert placeholder\n\nREQUIRED OUTPUT:\nProvide meta tags in the required format\n\nVALIDATION CRITERIA:\n- Verify that the meta title doesn't exceed 60 characters\n- Verify that the meta description doesn't exceed 160 characters\n- Check that both contain the main keyword\n- Ensure the language is persuasive and action-oriented\n- Confirm that meta tags are consistent with the content\n\nIMPORTANT:\n- Don't use excessive punctuation\n- Avoid using special characters unless necessary\n- Don't duplicate information between title and description\n- Maintain a professional yet accessible tone\n- Ensure content is unique and not duplicated\n\nRemember: the goal is to create meta tags that effectively balance SEO optimization and user appeal, maximizing the potential click-through rate in search results."
            }
          ]
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 1.5
    },
    {
      "id": "0c995efc-e28e-467d-9b17-d22e792ff0d3",
      "name": "Update product",
      "type": "n8n-nodes-base.wooCommerce",
      "position": [
        1120,
        -480
      ],
      "parameters": {
        "imagesUi": {},
        "resource": "product",
        "operation": "update",
        "productId": "={{ $('Get product ID').item.json['ID POST'] }}",
        "metadataUi": {
          "metadataValues": [
            {
              "key": "_yoast_wpseo_title",
              "value": "={{ $json.output.metatitle }}"
            },
            {
              "key": "_yoast_wpseo_metadesc",
              "value": "={{ $json.output.metadescription }}"
            }
          ]
        },
        "dimensionsUi": {},
        "updateFields": {}
      },
      "credentials": {
        "wooCommerceApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "e1850ecf-792a-4b78-addb-f433732a215c",
      "name": "Update Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1320,
        -480
      ],
      "parameters": {
        "columns": {
          "value": {
            "URL": "={{ $('Get product').item.json.permalink }}",
            "DATA": "={{ $now.format('dd/LL/yyyy HH:ii') }}",
            "METATITLE": "={{ $('Generate metatitle e metadescription').item.json.output.metatitle }}",
            "TITLE POST": "={{ $('Get product').item.json.name }}",
            "row_number": "={{ $('Get product ID').item.json.row_number }}",
            "METADESCRIPTION": "={{ $('Generate metatitle e metadescription').item.json.output.metadescription }}"
          },
          "schema": [
            {
              "id": "DATA",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "DATA",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ID POST",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "ID POST",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "TYPE POST",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "TYPE POST",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "URL",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "TITLE POST",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "TITLE POST",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "METATITLE",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "METATITLE",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "METADESCRIPTION",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "METADESCRIPTION",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "row_number"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1-eCFzNDrs1CiLJ4K5CSIaLeYt5Xf5PdubFNDvKWL-dA/edit#gid=0",
          "cachedResultName": "Foglio1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "17eYoKhtUupkye9Bmv13BjfP2jyymBUW4UYQGWU6V2cs",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17eYoKhtUupkye9Bmv13BjfP2jyymBUW4UYQGWU6V2cs/edit?usp=drivesdk",
          "cachedResultName": "Metatitle and Metadescription WooCommerce"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "a095dc5b-d234-40c5-9486-e34f24c1b1eb",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        280,
        -560
      ],
      "parameters": {
        "width": 180,
        "height": 240,
        "content": "Get the product ID that does not have metatitle or metadescription yet"
      },
      "typeVersion": 1
    },
    {
      "id": "bac079f9-890e-49e4-811e-31cf0cfb5d1b",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        480,
        -560
      ],
      "parameters": {
        "width": 180,
        "height": 240,
        "content": "Get all the product details starting from the product ID"
      },
      "typeVersion": 1
    },
    {
      "id": "c9c3d53a-a591-4ab4-8f81-c93edd3c5b9f",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        680,
        -560
      ],
      "parameters": {
        "width": 380,
        "height": 240,
        "content": "Based on the content of the product generates the metatitle and metadescription. In this example we use Gemini Think 2.0 which is FREE with OpenRouter"
      },
      "typeVersion": 1
    },
    {
      "id": "521240e4-fc75-45cc-a965-95d7d17dc727",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1080,
        -560
      ],
      "parameters": {
        "width": 180,
        "height": 240,
        "content": "Insert the generated data into WooCommerce"
      },
      "typeVersion": 1
    },
    {
      "id": "e8643582-c30a-4b16-8e15-15acc969a032",
      "name": "Gemini 2.0 Flash Exp",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "position": [
        740,
        -280
      ],
      "parameters": {
        "model": "google/gemini-2.0-flash-exp:free",
        "options": {}
      },
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "be9042a1-e2f8-4ed0-850d-269cf6fc55e8",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        280,
        -820
      ],
      "parameters": {
        "color": 3,
        "width": 980,
        "content": "WooCommerce SEO Yoast Meta Tag Generation for FREE\n\nThis workflow streamlines the process of optimizing WooCommerce product pages for SEO, saving time and ensuring consistency in meta tag generation.\n\nCreate a copy of [this Sheet](https://docs.google.com/spreadsheets/d/17eYoKhtUupkye9Bmv13BjfP2jyymBUW4UYQGWU6V2cs/edit?usp=sharing) and insert only the WooCommerce product ID in the column \"B\"."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "aa239f84-430a-4e3f-a33f-3552834e635e",
  "connections": {
    "Get product": {
      "main": [
        [
          {
            "node": "Generate metatitle e metadescription",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Sheet": {
      "main": [
        []
      ]
    },
    "Get product ID": {
      "main": [
        [
          {
            "node": "Get product",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update product": {
      "main": [
        [
          {
            "node": "Update Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gemini 2.0 Flash Exp": {
      "ai_languageModel": [
        [
          {
            "node": "Generate metatitle e metadescription",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Generate metatitle e metadescription",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "When clicking \u2018Test workflow\u2019": {
      "main": [
        [
          {
            "node": "Get product ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate metatitle e metadescription": {
      "main": [
        [
          {
            "node": "Update product",
            "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.

Pro

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

About this workflow

This workflow is designed to automate the generation and updating of SEO meta titles and descriptions for WooCommerce products using n8n. It leverages Google Sheets for data input, a FREE language model (Gemini 2.0 Flash Exp. via OpenRouter) for generating SEO-optimized meta…

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

More Data & Sheets workflows → · Browse all categories →

Related workflows

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

Data & Sheets

This workflow demonstrates a simple way to run evals on a set of test cases stored in a Google Sheet.

Google Sheets, Output Parser Structured, Chain Llm +3
Data & Sheets

This workflow demonstrates a simple way to run evals on a set of test cases stored in a Google Sheet.

OpenRouter Chat, Google Drive, Google Sheets +2
Data & Sheets

Splitout Code. Uses lmChatOpenRouter, outputParserStructured, httpRequest, stickyNote. Event-driven trigger; 11 nodes.

OpenRouter Chat, Output Parser Structured, HTTP Request +2
Data & Sheets

This workflow automates web scraping of Amazon search result pages by retrieving raw HTML, cleaning it to retain only the relevant product elements, and then using an LLM to extract structured product

OpenRouter Chat, Output Parser Structured, HTTP Request +2
Data & Sheets

This template is for educators, parents, or self-learners who want to gamify their study routines. It turns boring study logs into an interactive RPG math battle using AI.

Chain Llm, OpenRouter Chat, Output Parser Structured +2