AutomationFlows โ€บ AI & RAG โ€บ Optimize SEO Meta Tags in Google Sheets with Google Gemini

Optimize SEO Meta Tags in Google Sheets with Google Gemini

ByFederico De Ponte @fede on n8n.io

๐Ÿ” Loop & Optimize Meta Tags with Google Gemini

Cron / scheduled triggerโ˜…โ˜…โ˜…โ˜…โ˜† complexityAI-powered12 nodesGoogle SheetsGoogle Gemini ChatAgent
AI & RAG Trigger: Cron / scheduled Nodes: 12 Complexity: โ˜…โ˜…โ˜…โ˜…โ˜† AI nodes: yes Added:

This workflow corresponds to n8n.io template #5411 โ€” we link there as the canonical source.

This workflow follows the Agent โ†’ 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": "5YDxvfolrOk2nkjw",
  "name": "shorten-meta-tags-simple",
  "tags": [],
  "nodes": [
    {
      "id": "676dd82e-7ea8-4873-b2e7-07640d4800da",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -560,
        0
      ],
      "parameters": {
        "rule": {
          "interval": [
            {}
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "a6264ba1-4d30-4367-a9e4-627bce36cb91",
      "name": "If",
      "type": "n8n-nodes-base.if",
      "position": [
        160,
        0
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "55df6570-d9fd-4714-aeca-5d791a99c744",
              "operator": {
                "type": "string",
                "operation": "empty",
                "singleValue": true
              },
              "leftValue": "={{ $json['Content'] }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "9ba1fec2-59f4-4c11-b441-371476a9a7d9",
      "name": "Aggregate",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        960,
        0
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData"
      },
      "typeVersion": 1
    },
    {
      "id": "1ebdc3de-5bed-45ed-a9ff-031fb9d40b61",
      "name": "get-current-tags",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -320,
        0
      ],
      "parameters": {
        "options": {
          "returnFirstMatch": false
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1829282121,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1yIu9T1FikFvYjRdK8AQ0qdpUVatcxMG8QuStQc3EHrY/edit#gid=1829282121",
          "cachedResultName": "blog_content_sheet"
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": "https://docs.google.com/spreadsheets/d/1yIu9T1FikFvYjRdK8AQ0qdpUVatcxMG8QuStQc3EHrY/edit?gid=1829282121#gid=1829282121"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "7a3e6334-3cfc-43b8-8df9-3385ba28c9cc",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -120,
        0
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "87807836-f718-4cd6-a7e3-6752aa911ca8",
      "name": "Google Gemini Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        380,
        160
      ],
      "parameters": {
        "options": {
          "temperature": 0.4
        },
        "modelName": "models/gemini-2.0-flash"
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "fae37716-98cb-4982-b011-4af2bf665d0a",
      "name": "update-tags",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        400,
        0
      ],
      "parameters": {
        "text": "=## INPUT ##\n\nMeta Title: \"{{ $json.meta_title }}\"\nMeta Description: \"{{ $json.meta_description }}\"\n\n## TASK ##\n\nYou are an SEO assistant. Your task is to shorten the following:\n\nMeta Title: Limit to max 60 characters\n\nMeta Description: Limit to max 160 characters\n\nOnly shorten if necessary. When shortening:\n\nKeep all core keywords intact.\n\nDo not rewrite unless needed for shortening.\n\nMaintain the original meaning as closely as possible.\n\nBe concise and avoid filler words.\n\nJSON hierarchy MUST be flat and follow this exact format:  \n{\n  \"Index\": \"{{ $json.row_index }}\",  \n  \"meta_titleFixed\": \"Meta Title with <60 chars\",  \n  \"meta_descriptionFixed\": \"Meta Description with <160 chars\"\n}",
        "options": {},
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 1.7
    },
    {
      "id": "149059c8-12e7-45f7-894e-864015ba88fd",
      "name": "format-code",
      "type": "n8n-nodes-base.code",
      "position": [
        160,
        -180
      ],
      "parameters": {
        "jsCode": "// Function to recursively flatten nested objects\nfunction flattenObject(obj, prefix = '') {\n  let flatObject = {};\n  \n  for (let key in obj) {\n    if (typeof obj[key] === 'object' && obj[key] !== null) {\n      // Recursively flatten nested objects\n      Object.assign(flatObject, flattenObject(obj[key], prefix + key + '.'));\n    } else {\n      flatObject[prefix + key] = obj[key];\n    }\n  }\n\n  return flatObject;\n}\n\n// Function to transform nested JSON into a flat table structure\nfunction flattenToTable(inputData) {\n  if (!Array.isArray(inputData)) {\n    throw new Error('Invalid input data. Expected an array.');\n  }\n\n  // Result array for table rows\n  const tableRows = [];\n\n  // Loop over each item in the input data\n  inputData.forEach((item, index) => {\n    // Recursively flatten each data entry\n    let flatRow = flattenObject(item);\n\n    // Remove the \"json.data.0.\" prefix from each key\n    let cleanedRow = {};\n    for (let key in flatRow) {\n      let newKey = key.replace(/^json\\.data\\.0\\./, '');  // Strip the prefix\n      cleanedRow[newKey] = flatRow[key];\n    }\n\n    tableRows.push(cleanedRow);\n  });\n\n  console.log('Final Table Rows:', tableRows); // Debugging final table rows\n  return tableRows;\n}\n\n// Fetch the input data\nconst inputData = $input.all();\n\n// Flatten the data into a table-like structure\nconst table = flattenToTable(inputData);\n\n// Return the constructed table\nreturn table;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "70d530f5-d776-4aa0-85c3-380c255cf24c",
      "name": "save-output",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        400,
        -180
      ],
      "parameters": {
        "columns": {
          "value": {
            "row_index": "={{ $json.Index }}",
            "meta_titleFixed": "={{ $json.meta_titleFixed }}",
            "meta_descriptionFixed": "={{ $json.meta_descriptionFixed }}"
          },
          "schema": [
            {
              "id": "id",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "id",
              "defaultMatch": true,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_index",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "row_index",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "primary_keyword",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "primary_keyword",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "links",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "links",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "headline",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "headline",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "subtitle",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "subtitle",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "faq",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "faq",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "meta_title",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "meta_title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "meta_description",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "meta_description",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "meta_titleFixed",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "meta_titleFixed",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "meta_descriptionFixed",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "meta_descriptionFixed",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "key_takeaway_01",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "key_takeaway_01",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "key_takeaway_02",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "key_takeaway_02",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "key_takeaway_03",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "key_takeaway_03",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "teaser",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "teaser",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "intro",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "intro",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "lead_survey_title",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "lead_survey_title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "lead_survey_button",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "lead_survey_button",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "section_01_title",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "section_01_title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "section_01_content",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "section_01_content",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "section_02_title",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "section_02_title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "section_02_content",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "section_02_content",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "section_03_title",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "section_03_title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "section_03_content",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "section_03_content",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "section_04_title",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "section_04_title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "section_04_content",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "section_04_content",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "section_05_title",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "section_05_title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "section_05_content",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "section_05_content",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "section_06_title",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "section_06_title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "section_06_content",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "section_06_content",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "section_07_title",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "section_07_title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "section_07_content",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "section_07_content",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "section_08_title",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "section_08_title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "section_08_content",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "section_08_content",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "section_09_title",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "section_09_title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "section_09_content",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "section_09_content",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "format",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "format",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "table_name",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "table_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "company_name",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "company_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "company_url",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "company_url",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "image_1_alt",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "image_1_alt",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "image_1",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "image_1",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "image_2",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "image_2",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "image_3",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "image_3",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "slug",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "slug",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "image_headline",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "image_headline",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "image_2_alt",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "image_2_alt",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "image_3_alt",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "image_3_alt",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "image_headline_alt",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "image_headline_alt",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "target_word_count",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "target_word_count",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "target_section_count",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "target_section_count",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "generation_status",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "generation_status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "wip_timestamp",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "wip_timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "more_links",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "more_links",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "solution",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "solution",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "subsolution",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "subsolution",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Index",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Index",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Meta TitleFixed",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Meta TitleFixed",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Meta DescriptionFixed",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Meta DescriptionFixed",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "pairedItem.item",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "pairedItem.item",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "pairedItem.input",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "pairedItem.input",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "meta_dscriptionFixed",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "meta_dscriptionFixed",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "row_index"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1829282121,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1yIu9T1FikFvYjRdK8AQ0qdpUVatcxMG8QuStQc3EHrY/edit#gid=1829282121",
          "cachedResultName": "blog_content_sheet"
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": "https://docs.google.com/spreadsheets/d/1yIu9T1FikFvYjRdK8AQ0qdpUVatcxMG8QuStQc3EHrY/edit?gid=1829282121#gid=1829282121"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "f596a9da-b212-4148-94d0-a53078e103e1",
      "name": "turn-into-table",
      "type": "n8n-nodes-base.code",
      "position": [
        760,
        0
      ],
      "parameters": {
        "jsCode": "try {\n  // 1. Get raw output from the input JSON\n  const rawOutput = $input.first().json.output || \"\";\n\n  // 2. Extract JSON from code fences, if present (supports json, html, or other language tags)\n  const jsonMatch = rawOutput.match(/```(?:json|html|[a-zA-Z]*)\\s*([\\s\\S]*?)\\s*```/);\n  let cleanedOutput = jsonMatch ? jsonMatch[1] : rawOutput;\n\n  // 3. Remove potential HTML wrappers like DOCTYPE, <html>, <head>, <body> tags\n  cleanedOutput = cleanedOutput.replace(\n    /<!DOCTYPE[^>]*>|<html[^>]*>|<\\/html>|<head[^>]*>[\\s\\S]*?<\\/head>|<body[^>]*>|<\\/body>/gi,\n    ''\n  );\n\n  // 4. Remove potential BOM (byte order mark) and trim whitespace\n  cleanedOutput = cleanedOutput.replace(/^\\uFEFF/, '').trim();\n\n  // 5. Sanitize control characters while preserving newlines (\\n), carriage returns (\\r), and tabs (\\t)\n  cleanedOutput = cleanedOutput.replace(/[\\u0000-\\u001F\\u007F]/g, (char) => {\n    return (char === '\\n' || char === '\\r' || char === '\\t') ? char : ' ';\n  });\n\n  // 6. Additional sanitization: flatten HTML content within JSON string fields\n  //    Remove spaces between tags and collapse multiple spaces into one.\n  cleanedOutput = cleanedOutput.replace(/>\\s+</g, '><').replace(/\\s+/g, ' ').trim();\n\n  // 7. Try to parse the JSON. If it fails, attempt further sanitization by escaping unescaped double quotes in HTML text\n  let parsedData;\n  try {\n    parsedData = JSON.parse(cleanedOutput);\n  } catch (parseError) {\n    // Fallback: Escape all double quotes that occur between a '>' and a '<'\n    const furtherSanitizedOutput = cleanedOutput.replace(/>([^<]+)</g, (match, p1) => {\n      // Replace all double quotes in the text content with escaped ones\n      return '>' + p1.replace(/\"/g, '\\\\\"') + '<';\n    });\n    parsedData = JSON.parse(furtherSanitizedOutput);\n  }\n\n  // 8. Function to convert HTML content fields to a single-line format\n  function convertHtmlToSingleLine(data) {\n    if (typeof data === 'string') {\n      return data\n        .replace(/[\\n\\r]+/g, ' ')  // Remove all newline and carriage return characters\n        .replace(/\\s+/g, ' ')      // Collapse multiple spaces into one\n        .trim();\n    } else if (Array.isArray(data)) {\n      return data.map(item => convertHtmlToSingleLine(item));\n    } else if (typeof data === 'object' && data !== null) {\n      const newObj = {};\n      for (const key in data) {\n        if (data.hasOwnProperty(key)) {\n          newObj[key] = convertHtmlToSingleLine(data[key]);\n        }\n      }\n      return newObj;\n    }\n    return data;\n  }\n\n  // 9. Apply the HTML conversion to the parsed data\n  parsedData = convertHtmlToSingleLine(parsedData);\n\n  // 10. Dynamically format the output:\n  //     If parsedData is an array, return it; if it\u2019s an object, wrap it in an array.\n  let formattedOutput;\n  if (Array.isArray(parsedData)) {\n    formattedOutput = parsedData.map(item => {\n      const dynamicObject = {};\n      for (const key in item) {\n        if (item.hasOwnProperty(key)) {\n          dynamicObject[key] = item[key];\n        }\n      }\n      return dynamicObject;\n    });\n  } else if (typeof parsedData === 'object' && parsedData !== null) {\n    const dynamicObject = {};\n    for (const key in parsedData) {\n      if (parsedData.hasOwnProperty(key)) {\n        dynamicObject[key] = parsedData[key];\n      }\n    }\n    formattedOutput = [dynamicObject];\n  } else {\n    throw new Error(\"Unsupported JSON format. Expected an array or object.\");\n  }\n\n  // 11. Return the formatted output\n  return formattedOutput;\n\n} catch (error) {\n  throw new Error(\"Failed to parse JSON output: \" + error.message);\n}\n"
      },
      "executeOnce": true,
      "typeVersion": 2
    },
    {
      "id": "8fb3573b-8abf-45df-924b-9a08e612eb34",
      "name": "Sticky \u2014 Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -560,
        -200
      ],
      "parameters": {
        "width": 420,
        "height": 320,
        "content": "## How it works\n- Reads rows from a connected Google Sheet\n- Processes each row using Google Gemini to shorten meta titles and descriptions\n- Ensures SEO constraints (\u2264\u00a060\u00a0chars for titles, \u2264\u00a0160\u00a0chars for descriptions)\n- Preserves core keywords and original meaning\n- Cleans and flattens Gemini output\n- Writes results back to the sheet"
      },
      "typeVersion": 1
    },
    {
      "id": "346507ba-2ee2-4569-a089-7cf39119f749",
      "name": "Sticky \u2014 Setup",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -120,
        -200
      ],
      "parameters": {
        "width": 440,
        "height": 340,
        "content": "## Setup steps\n- Estimated setup time: 10\u201315\u00a0min\n- Google Sheets OAuth2 credentials\n- Google Gemini API key\n- Sheet columns: `row_index`, `meta_title`, `meta_description`\n- Output columns `meta_titleFixed` & `meta_descriptionFixed`\n- Error handling & formatting built\u2011in\n- Prompt editable in \u201cupdate-tags\u201d node"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "callerPolicy": "workflowsFromSameOwner",
    "executionOrder": "v1",
    "saveDataSuccessExecution": "all"
  },
  "versionId": "8f49c63c-49cc-4e00-b745-f0c30ee87f5b",
  "connections": {
    "If": {
      "main": [
        [
          {
            "node": "update-tags",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "format-code": {
      "main": [
        [
          {
            "node": "save-output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "update-tags": {
      "main": [
        [
          {
            "node": "turn-into-table",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [
          {
            "node": "format-code",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "turn-into-table": {
      "main": [
        [
          {
            "node": "Aggregate",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "get-current-tags",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "get-current-tags": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "update-tags",
            "type": "ai_languageModel",
            "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

๐Ÿ” Loop & Optimize Meta Tags with Google Gemini

Source: https://n8n.io/workflows/5411/ โ€” original creator credit. Request a take-down โ†’

More AI & RAG workflows โ†’ ยท Browse all categories โ†’

Related workflows

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

AI & RAG

The Multi-Model Agency Content Engine is a high-performance editorial system designed for agencies. It solves the "blank page" problem by alternating between real-world social proof and strategic expe

Google Sheets, Gmail, Google Drive +6
AI & RAG

This workflow automates the complete blog publishing process. It removes manual work from content creation, image generation, category management, and WordPress publishing by using AI and n8n. It help

Google Gemini Chat, Output Parser Structured, Lm Chat Deep Seek +5
AI & RAG

This project is an automated news publisher for LinkedIn. It uses RSS feeds to fetch news, processes the content with the Gemini API to generate precise summaries, and automatically publishes to Linke

Agent, Google Gemini Chat, RSS Feed Read +4
AI & RAG

This template is for clinics, hospitals, care teams, and telemedicine providers who need a structured, automated system for post-surgery follow-up. It helps reduce manual workload while ensuring every

Google Sheets, Telegram, Telegram Trigger +7
AI & RAG

This workflow is the AI analysis and alerting engine for a complete social media monitoring system. It's designed to work with data scraped from X (formerly Twitter) using a tool like the Apify Tweet

Google Sheets, Google Gemini Chat, Google Sheets Tool +4