{"id":2769,"date":"2025-10-21T14:32:52","date_gmt":"2025-10-21T12:32:52","guid":{"rendered":"https:\/\/edukia.org\/?post_type=avada_portfolio&#038;p=2769"},"modified":"2025-11-07T16:26:39","modified_gmt":"2025-11-07T15:26:39","slug":"generador-seo-per-a-wordpress","status":"publish","type":"avada_portfolio","link":"https:\/\/edukia.org\/ca\/recursos\/generador-seo-per-a-wordpress\/","title":{"rendered":"Generador SEO per a WordPress"},"content":{"rendered":"<p><div class=\"fusion-fullwidth fullwidth-box fusion-builder-row-1 fusion-flex-container has-pattern-background has-mask-background nonhundred-percent-fullwidth non-hundred-percent-height-scrolling\" style=\"--awb-border-radius-top-left:10px;--awb-border-radius-top-right:10px;--awb-border-radius-bottom-right:10px;--awb-border-radius-bottom-left:10px;--awb-overflow:hidden;--awb-padding-top:30px;--awb-padding-bottom:30px;--awb-background-color:#eaeaea;--awb-flex-wrap:wrap;\" ><div class=\"fusion-builder-row fusion-row fusion-flex-align-items-flex-start fusion-flex-content-wrap\" style=\"max-width:1310.4px;margin-left: calc(-4% \/ 2 );margin-right: calc(-4% \/ 2 );\"><div class=\"fusion-layout-column fusion_builder_column fusion-builder-column-0 fusion_builder_column_1_1 1_1 fusion-flex-column\" style=\"--awb-bg-size:cover;--awb-width-large:100%;--awb-margin-top-large:0px;--awb-spacing-right-large:1.92%;--awb-margin-bottom-large:20px;--awb-spacing-left-large:1.92%;--awb-width-medium:100%;--awb-order-medium:0;--awb-spacing-right-medium:1.92%;--awb-spacing-left-medium:1.92%;--awb-width-small:100%;--awb-order-small:0;--awb-spacing-right-small:1.92%;--awb-spacing-left-small:1.92%;\"><div class=\"fusion-column-wrapper fusion-column-has-shadow fusion-flex-justify-content-flex-start fusion-content-layout-column\"><div class=\"fusion-text fusion-text-1\"><h1><\/h1>\n<h3 data-pm-slice=\"1 1 &#091;&#093;\">\u00a1Revoluciona tu SEO y Atrae Todas las Miradas!<\/h3>\n<p>\u00bfCansado de pelear con el SEO y de buscar la imagen perfecta para tus art\u00edculos? \u00a1Se acab\u00f3! Te presentamos nuestra nueva herramienta con IA, dise\u00f1ada para llevar tu contenido al siguiente nivel.<\/p>\n<p>Con solo pegar tu texto, obtendr\u00e1s al instante las <strong>palabras clave exactas<\/strong> que necesitas para conquistar Google y una <strong>descripci\u00f3n SEO magn\u00e9tica<\/strong> que disparar\u00e1 tus clics. Pero eso no es todo: nuestra IA tambi\u00e9n crear\u00e1 <strong>tres im\u00e1genes espectaculares y \u00fanicas<\/strong> para tu post, listas para que elijas la que mejor conecte con tu audiencia.<\/p>\n<p><strong>Deja de adivinar y empieza a posicionar.<\/strong> Transforma tu blog, ahorra horas de trabajo y crea contenido que no solo se lea, sino que tambi\u00e9n impacte.<\/p>\n<\/div><\/div><\/div><\/div><\/div><div class=\"fusion-fullwidth fullwidth-box fusion-builder-row-2 fusion-flex-container has-pattern-background has-mask-background hundred-percent-fullwidth non-hundred-percent-height-scrolling\" style=\"--awb-border-radius-top-left:0px;--awb-border-radius-top-right:0px;--awb-border-radius-bottom-right:10px;--awb-border-radius-bottom-left:10px;--awb-overflow:hidden;--awb-background-color:#eaeaea;--awb-flex-wrap:wrap;\" ><div class=\"fusion-builder-row fusion-row fusion-flex-align-items-flex-start fusion-flex-content-wrap\" style=\"width:104% !important;max-width:104% !important;margin-left: calc(-4% \/ 2 );margin-right: calc(-4% \/ 2 );\"><div class=\"fusion-layout-column fusion_builder_column fusion-builder-column-1 fusion_builder_column_1_1 1_1 fusion-flex-column\" style=\"--awb-bg-size:cover;--awb-width-large:100%;--awb-margin-top-large:0px;--awb-spacing-right-large:1.92%;--awb-margin-bottom-large:20px;--awb-spacing-left-large:1.92%;--awb-width-medium:100%;--awb-order-medium:0;--awb-spacing-right-medium:1.92%;--awb-spacing-left-medium:1.92%;--awb-width-small:100%;--awb-order-small:0;--awb-spacing-right-small:1.92%;--awb-spacing-left-small:1.92%;\"><div class=\"fusion-column-wrapper fusion-column-has-shadow fusion-flex-justify-content-flex-start fusion-content-layout-column\"><!DOCTYPE html>\n<html lang=\"es\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Asistente SEO con Generador M\u00faltiple de Im\u00e1genes<\/title>\n    <script src=\"https:\/\/cdn.tailwindcss.com\"><\/script>\n    <link rel=\"stylesheet\" href=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/font-awesome\/6.4.0\/css\/all.min.css\">\n    <link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n    <link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin>\n    <link href=\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;500;600;700&display=swap\" rel=\"stylesheet\">\n    <style>\n        body {\n            font-family: 'Inter', sans-serif;\n        }\n        .fade-in {\n            animation: fadeIn 0.5s ease-in-out;\n        }\n        @keyframes fadeIn {\n            from { opacity: 0; transform: translateY(10px); }\n            to { opacity: 1; transform: translateY(0); }\n        }\n        @keyframes spin {\n            to { transform: rotate(360deg); }\n        }\n        .spinner {\n            animation: spin 1s linear infinite;\n        }\n        .copy-btn, .download-btn {\n            transition: all 0.2s ease-in-out;\n        }\n        .copy-btn:hover, .download-btn:hover {\n            transform: scale(1.1);\n        }\n        .copy-btn:active, .download-btn:active {\n            transform: scale(0.95);\n        }\n    <\/style>\n<\/head>\n<body class=\"bg-gray-50 text-gray-800 flex items-center justify-center min-h-screen\">\n    <div class=\"container mx-auto p-4 md:p-8 max-w-4xl\">\n        <div class=\"bg-white rounded-2xl shadow-lg p-6 md:p-10\">\n            \n            <div class=\"mb-8\">\n                <h2 class=\"text-2xl font-bold text-gray-900 text-center mb-6\">Pasos para Optimizar tu Contenido<\/h2>\n                <ol class=\"space-y-4\">\n                    <li class=\"flex items-start\">\n                        <div class=\"flex-shrink-0 bg-red-500 text-white rounded-full h-8 w-8 flex items-center justify-center font-bold mr-4\">1<\/div>\n                        <div>\n                            <h3 class=\"font-semibold text-gray-800\">Introduce tu API Key<\/h3>\n                            <p class=\"text-gray-600\">Pega tu clave API de Google AI. Es necesaria para que la herramienta funcione. <a href=\"https:\/\/aistudio.google.com\/app\/apikey\" target=\"_blank\" class=\"text-blue-600 hover:underline\" rel=\"noopener\">Consigue una aqu\u00ed<\/a>.<\/p>\n                        <\/div>\n                    <\/li>\n                    <li class=\"flex items-start\">\n                        <div class=\"flex-shrink-0 bg-blue-500 text-white rounded-full h-8 w-8 flex items-center justify-center font-bold mr-4\">2<\/div>\n                        <div>\n                            <h3 class=\"font-semibold text-gray-800\">Pega tu Art\u00edculo<\/h3>\n                            <p class=\"text-gray-600\">Introduce el texto de tu post (m\u00ednimo 100 palabras) en el \u00e1rea de contenido principal.<\/p>\n                        <\/div>\n                    <\/li>\n                    <li class=\"flex items-start\">\n                        <div class=\"flex-shrink-0 bg-blue-500 text-white rounded-full h-8 w-8 flex items-center justify-center font-bold mr-4\">3<\/div>\n                        <div>\n                            <h3 class=\"font-semibold text-gray-800\">Analiza el SEO<\/h3>\n                            <p class=\"text-gray-600\">Haz clic en \"Analizar SEO\" para recibir tu palabra clave objetivo, secundarias y la meta descripci\u00f3n optimizada.<\/p>\n                        <\/div>\n                    <\/li>\n                    <li class=\"flex items-start\">\n                        <div class=\"flex-shrink-0 bg-green-500 text-white rounded-full h-8 w-8 flex items-center justify-center font-bold mr-4\">4<\/div>\n                        <div>\n                            <h3 class=\"font-semibold text-gray-800\">Genera Im\u00e1genes<\/h3>\n                            <p class=\"text-gray-600\">Pulsa \"Generar Im\u00e1genes\" para crear tres opciones visuales \u00fanicas y relevantes para tu art\u00edculo.<\/p>\n                            <p class=\"text-xs text-gray-500 mt-1\">Nota: Esta funci\u00f3n requiere tener la <a href=\"https:\/\/cloud.google.com\/billing\/docs?hl=es\" target=\"_blank\" class=\"text-blue-600 hover:underline\" rel=\"noopener\">facturaci\u00f3n activada<\/a> en tu proyecto de Google Cloud.<\/p>\n                        <\/div>\n                    <\/li>\n                     <li class=\"flex items-start\">\n                        <div class=\"flex-shrink-0 bg-purple-500 text-white rounded-full h-8 w-8 flex items-center justify-center font-bold mr-4\">5<\/div>\n                        <div>\n                            <h3 class=\"font-semibold text-gray-800\">Copia y Descarga<\/h3>\n                            <p class=\"text-gray-600\">Usa los botones para copiar los datos SEO y descargar tu imagen preferida en formato JPG (1024x1024px).<\/p>\n                        <\/div>\n                    <\/li>\n                <\/ol>\n            <\/div>\n\n            <div class=\"space-y-6 border-t pt-8\">\n                 <div>\n                    <label for=\"api-key-input\" class=\"block text-sm font-medium text-gray-700 mb-2\">Google AI API Key:<\/label>\n                    <input type=\"password\" id=\"api-key-input\" class=\"w-full p-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-red-500 focus:border-red-500 transition duration-150\" placeholder=\"Pega tu API Key aqu\u00ed...\">\n                <\/div>\n                <div>\n                    <label for=\"article-text\" class=\"block text-sm font-medium text-gray-700 mb-2\">Contenido de tu art\u00edculo:<\/label>\n                    <textarea id=\"article-text\" rows=\"15\" class=\"w-full p-4 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition duration-150\" placeholder=\"Escribe o pega aqu\u00ed tu texto (m\u00ednimo 100 palabras)...\"><\/textarea>\n                    <p id=\"word-count\" class=\"text-sm text-gray-500 mt-2 text-right\">0 palabras<\/p>\n                <\/div>\n\n                <div class=\"flex flex-col sm:flex-row justify-center items-center gap-4\">\n                    <button id=\"analyze-btn\" class=\"w-full sm:w-auto bg-blue-600 text-white font-bold py-3 px-8 rounded-xl hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition-transform transform hover:scale-105 duration-200 disabled:bg-gray-400 disabled:cursor-not-allowed disabled:scale-100\">\n                        <span id=\"btn-text-seo\">Analizar SEO<\/span>\n                        <i id=\"loading-spinner-seo\" class=\"fas fa-spinner hidden ml-2\"><\/i>\n                    <\/button>\n                    <button id=\"generate-image-btn\" class=\"w-full sm:w-auto bg-green-600 text-white font-bold py-3 px-8 rounded-xl hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 transition-transform transform hover:scale-105 duration-200 disabled:bg-gray-400 disabled:cursor-not-allowed disabled:scale-100\">\n                        <span id=\"btn-text-image\">Generar Im\u00e1genes<\/span>\n                        <i id=\"loading-spinner-image\" class=\"fas fa-spinner hidden ml-2\"><\/i>\n                    <\/button>\n                <\/div>\n            <\/div>\n\n            <!-- Results Section --><div id=\"results-container\" class=\"mt-10 border-t pt-8 space-y-8 hidden\">\n                <h2 id=\"results-title\" class=\"text-2xl font-bold text-center text-gray-900 hidden\">Resultados<\/h2>\n                \n                <!-- SEO Results --><div id=\"seo-results-wrapper\">\n                    <!-- Target Keyword --><div id=\"focus-keyword-section\" class=\"bg-gray-100 p-5 rounded-xl fade-in hidden mb-6\">\n                        <h3 class=\"text-lg font-semibold text-gray-800 mb-3\">Palabra Clave Objetivo<\/h3>\n                        <div class=\"flex items-center justify-between bg-white p-3 rounded-lg shadow-sm\">\n                            <p id=\"focus-keyword\" class=\"text-blue-700 font-medium\"><\/p>\n                            <button onclick=\"copyToClipboard('focus-keyword')\" class=\"copy-btn text-gray-500 hover:text-blue-600\" title=\"Copiar al portapapeles\"><i class=\"far fa-copy\"><\/i><\/button>\n                        <\/div>\n                        <p class=\"text-xs text-gray-500 mt-2\">Usa esta como tu \"Focus Keyword\" en Rank Math.<\/p>\n                    <\/div>\n                    \n                    <!-- Secondary Keywords --><div id=\"secondary-keywords-section\" class=\"bg-gray-100 p-5 rounded-xl fade-in hidden mb-6\">\n                        <h3 class=\"text-lg font-semibold text-gray-800 mb-3\">Palabras Clave Secundarias<\/h3>\n                        <div id=\"secondary-keywords-list\" class=\"flex flex-wrap gap-2\"><\/div>\n                        <div class=\"relative mt-3\">\n                            <input id=\"secondary-keywords-input\" type=\"text\" readonly class=\"w-full bg-white p-3 rounded-lg shadow-sm pr-10 text-gray-600\">\n                            <button onclick=\"copyToClipboard('secondary-keywords-input')\" class=\"copy-btn absolute top-1\/2 right-3 -translate-y-1\/2 text-gray-500 hover:text-blue-600\" title=\"Copiar al portapapeles\"><i class=\"far fa-copy\"><\/i><\/button>\n                        <\/div>\n                        <p class=\"text-xs text-gray-500 mt-2\">A\u00f1ade estas palabras clave adicionales en Rank Math.<\/p>\n                    <\/div>\n                    \n                    <!-- SEO Description --><div id=\"seo-description-section\" class=\"bg-gray-100 p-5 rounded-xl fade-in hidden\">\n                        <h3 class=\"text-lg font-semibold text-gray-800 mb-3\">Descripci\u00f3n SEO (Meta Description)<\/h3>\n                        <div class=\"relative\">\n                            <p id=\"seo-description\" class=\"bg-white p-4 rounded-lg shadow-sm text-gray-700 leading-relaxed\"><\/p>\n                            <button onclick=\"copyToClipboard('seo-description')\" class=\"copy-btn absolute top-3 right-3 text-gray-500 hover:text-blue-600\" title=\"Copiar al portapapeles\"><i class=\"far fa-copy\"><\/i><\/button>\n                        <\/div>\n                        <p id=\"description-char-count\" class=\"text-xs text-gray-500 mt-2 text-right\">0 caracteres<\/p>\n                        <p class=\"text-xs text-gray-500 mt-1\">Pega esto en el campo \"Description\" del Snippet Editor de Rank Math.<\/p>\n                    <\/div>\n                <\/div>\n\n                <!-- Image Generation Result --><div id=\"image-generation-section\" class=\"bg-gray-100 p-5 rounded-xl fade-in hidden\">\n                    <h3 class=\"text-lg font-semibold text-gray-800 mb-3\">Im\u00e1genes Sugeridas para el Art\u00edculo<\/h3>\n                    <div id=\"images-grid\" class=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n                        <!-- Image cards will be injected here --><\/div>\n                    <div id=\"image-loader\" class=\"text-center p-4 hidden\">\n                        <i class=\"fas fa-spinner fa-spin text-4xl text-gray-400\"><\/i>\n                        <p class=\"mt-2 text-gray-600\">Generando im\u00e1genes, esto puede tardar un momento...<\/p>\n                    <\/div>\n                    <p id=\"image-error\" class=\"text-red-600 p-4 hidden text-center\"><\/p>\n                <\/div>\n\n                 <!-- General Error Message --><div id=\"error-message\" class=\"bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded-xl relative hidden fade-in\" role=\"alert\">\n                    <strong class=\"font-bold\">\u00a1Error!<\/strong>\n                    <span class=\"block sm:inline\" id=\"error-text\"><\/span>\n                <\/div>\n            <\/div>\n        <\/div>\n        <footer class=\"text-center text-gray-500 text-sm mt-6 pb-4\">\n            <p>Desarrollado con IA<\/p>\n        <\/footer>\n    <\/div>\n    \n    <div id=\"toast\" class=\"fixed bottom-5 right-5 bg-gray-900 text-white py-2 px-4 rounded-lg shadow-lg transform translate-y-20 opacity-0 transition-all duration-300\">\n        \u00a1Copiado al portapapeles!\n    <\/div>\n\n    <script>\n        const articleText = document.getElementById('article-text');\n        const apiKeyInput = document.getElementById('api-key-input');\n        const analyzeBtn = document.getElementById('analyze-btn');\n        const generateImageBtn = document.getElementById('generate-image-btn');\n        const btnTextSeo = document.getElementById('btn-text-seo');\n        const loadingSpinnerSeo = document.getElementById('loading-spinner-seo');\n        const btnTextImage = document.getElementById('btn-text-image');\n        const loadingSpinnerImage = document.getElementById('loading-spinner-image');\n        const resultsContainer = document.getElementById('results-container');\n        const resultsTitle = document.getElementById('results-title');\n        const wordCountEl = document.getElementById('word-count');\n\n        \/\/ SEO Result elements\n        const seoResultsWrapper = document.getElementById('seo-results-wrapper');\n        const focusKeywordSection = document.getElementById('focus-keyword-section');\n        const secondaryKeywordsSection = document.getElementById('secondary-keywords-section');\n        const seoDescriptionSection = document.getElementById('seo-description-section');\n        const focusKeywordEl = document.getElementById('focus-keyword');\n        const secondaryKeywordsListEl = document.getElementById('secondary-keywords-list');\n        const secondaryKeywordsInputEl = document.getElementById('secondary-keywords-input');\n        const seoDescriptionEl = document.getElementById('seo-description');\n        const descriptionCharCountEl = document.getElementById('description-char-count');\n        \n        \/\/ Image Result elements\n        const imageGenerationSection = document.getElementById('image-generation-section');\n        const imagesGrid = document.getElementById('images-grid');\n        const imageLoader = document.getElementById('image-loader');\n        const imageError = document.getElementById('image-error');\n\n        \/\/ General Error\n        const errorMessageEl = document.getElementById('error-message');\n        const errorTextEl = document.getElementById('error-text');\n\n        function updateButtonState() {\n            const text = articleText.value.trim();\n            const words = text.split(\/\\s+\/).filter(word => word.length > 0);\n            const wordCount = words.length;\n            wordCountEl.textContent = `${wordCount} palabras`;\n            const key = apiKeyInput.value.trim();\n            \n            const isEnabled = wordCount >= 100 && key !== '';\n            analyzeBtn.disabled = !isEnabled;\n            generateImageBtn.disabled = !isEnabled;\n        }\n        \n        articleText.addEventListener('input', updateButtonState);\n        apiKeyInput.addEventListener('input', updateButtonState);\n\n        analyzeBtn.disabled = true;\n        generateImageBtn.disabled = true;\n\n        analyzeBtn.addEventListener('click', analyzeSeoText);\n        generateImageBtn.addEventListener('click', generateImagesForText);\n\n        function showSeoLoading(isLoading) {\n            if (isLoading) {\n                btnTextSeo.textContent = 'Analizando...';\n                loadingSpinnerSeo.classList.remove('hidden');\n                loadingSpinnerSeo.classList.add('spinner');\n                analyzeBtn.disabled = true;\n                generateImageBtn.disabled = true;\n            } else {\n                btnTextSeo.textContent = 'Analizar SEO';\n                loadingSpinnerSeo.classList.add('hidden');\n                loadingSpinnerSeo.classList.remove('spinner');\n                updateButtonState();\n            }\n        }\n        \n        function showImageLoading(isLoading) {\n             if (isLoading) {\n                btnTextImage.textContent = 'Generando...';\n                loadingSpinnerImage.classList.remove('hidden');\n                loadingSpinnerImage.classList.add('spinner');\n                generateImageBtn.disabled = true;\n                analyzeBtn.disabled = true;\n                imageLoader.classList.remove('hidden');\n                imagesGrid.innerHTML = ''; \/\/ Clear previous images\n                imageError.classList.add('hidden');\n            } else {\n                btnTextImage.textContent = 'Generar Im\u00e1genes';\n                loadingSpinnerImage.classList.add('hidden');\n                loadingSpinnerImage.classList.remove('spinner');\n                updateButtonState();\n                imageLoader.classList.add('hidden');\n            }\n        }\n\n        function hideAllResults() {\n             resultsTitle.classList.add('hidden');\n             focusKeywordSection.classList.add('hidden');\n             secondaryKeywordsSection.classList.add('hidden');\n             seoDescriptionSection.classList.add('hidden');\n             imageGenerationSection.classList.add('hidden');\n             errorMessageEl.classList.add('hidden');\n        }\n\n        async function analyzeSeoText() {\n            if (apiKeyInput.value.trim() === '') {\n                showError(\"Por favor, introduce tu API Key de Google AI para continuar.\");\n                return;\n            }\n            const textToAnalyze = articleText.value;\n            if (textToAnalyze.trim().split(\/\\s+\/).filter(Boolean).length < 100) {\n                 showError(\"Por favor, introduce un texto de al menos 100 palabras para analizarlo correctamente.\");\n                return;\n            }\n            resultsContainer.classList.remove('hidden');\n            resultsTitle.classList.remove('hidden');\n            imageGenerationSection.classList.add('hidden'); \n            seoResultsWrapper.classList.remove('hidden'); \n            errorMessageEl.classList.add('hidden');\n            showSeoLoading(true);\n\n            const systemPrompt = \"Act\u00faas como un experto en SEO especializado en el plugin Rank Math para WordPress. Tu tarea es analizar el texto proporcionado y generar los elementos clave para optimizarlo. Devuelve el resultado en formato JSON, siguiendo el schema proporcionado. La descripci\u00f3n SEO debe ser atractiva, incitar al clic y no superar los 160 caracteres.\";\n            const userPrompt = `Analiza el siguiente texto y, bas\u00e1ndote en \u00e9l, genera:\\n1.  Una \"focusKeyword\": la palabra clave objetivo principal m\u00e1s importante.\\n2.  Un array \"secondaryKeywords\" con 4 o 5 palabras clave secundarias muy relevantes.\\n3.  Una \"seoDescription\": una meta descripci\u00f3n optimizada de entre 150 y 160 caracteres que incluya la palabra clave objetivo de forma natural.\\n\\nTexto para analizar:\\n---\\n${textToAnalyze}\\n---`;\n            const payload = {\n                contents: [{ parts: [{ text: userPrompt }] }],\n                systemInstruction: { parts: [{ text: systemPrompt }] },\n                generationConfig: {\n                    responseMimeType: \"application\/json\",\n                    responseSchema: {\n                        type: \"OBJECT\",\n                        properties: { \"focusKeyword\": { \"type\": \"STRING\" }, \"secondaryKeywords\": { \"type\": \"ARRAY\", \"items\": { \"type\": \"STRING\" } }, \"seoDescription\": { \"type\": \"STRING\" } },\n                        required: [\"focusKeyword\", \"secondaryKeywords\", \"seoDescription\"]\n                    }\n                }\n            };\n            try {\n                const result = await makeApiCallWithRetry(`https:\/\/generativelanguage.googleapis.com\/v1beta\/models\/gemini-2.5-flash-preview-09-2025:generateContent`, payload);\n                displaySeoResults(result);\n            } catch (error) {\n                console.error('Error fetching SEO data:', error);\n                showError(`No se pudieron obtener las sugerencias SEO. Error: ${error.message}`);\n            } finally {\n                showSeoLoading(false);\n            }\n        }\n\n        async function generateImagesForText() {\n            if (apiKeyInput.value.trim() === '') {\n                showError(\"Por favor, introduce tu API Key de Google AI para continuar.\");\n                return;\n            }\n            const textToAnalyze = articleText.value;\n            if (textToAnalyze.trim().split(\/\\s+\/).filter(Boolean).length < 100) {\n                 showError(\"Por favor, introduce un texto de al menos 100 palabras para generar im\u00e1genes.\");\n                return;\n            }\n            resultsContainer.classList.remove('hidden');\n            resultsTitle.classList.remove('hidden');\n            seoResultsWrapper.classList.add('hidden'); \n            errorMessageEl.classList.add('hidden');\n            imageGenerationSection.classList.remove('hidden');\n            showImageLoading(true);\n\n            const userPrompt = `Generate three distinct, high-quality, photorealistic images, cinematic, detailed, highly aesthetic, without any text, illustrating different aspects or interpretations of the core concept of the following text: ${textToAnalyze.substring(0, 800)}`;\n            const payload = { instances: [{ prompt: userPrompt }], parameters: { \"sampleCount\": 3} }; \n\n            try {\n                const result = await makeApiCallWithRetry(`https:\/\/generativelanguage.googleapis.com\/v1beta\/models\/imagen-3.0-generate-002:predict`, payload);\n                displayImageResults(result);\n            } catch (error) {\n                console.error('Error generating images:', error);\n                showImageError(`No se pudieron generar las im\u00e1genes. Error: ${error.message}`);\n            } finally {\n                showImageLoading(false);\n            }\n        }\n\n        async function makeApiCallWithRetry(apiUrl, payload, retries = 3, delay = 1000) {\n            const apiKey = apiKeyInput.value.trim();\n            const fullApiUrl = `${apiUrl}?key=${apiKey}`;\n\n            for (let i = 0; i < retries; i++) {\n                try {\n                    const response = await fetch(fullApiUrl, {\n                        method: 'POST',\n                        headers: { 'Content-Type': 'application\/json' },\n                        body: JSON.stringify(payload)\n                    });\n                    if (!response.ok) {\n                        let errorData = { message: `Error HTTP: ${response.status}` };\n                        try {\n                           errorData = await response.json();\n                        } catch (e) { \/* ignore *\/ }\n                        const errorMessage = errorData.error?.message || JSON.stringify(errorData);\n                        throw new Error(errorMessage);\n                    }\n                    \n                    const data = await response.json();\n                    \n                    if (apiUrl.includes('generateContent')) { \n                        if (data.candidates?.[0]?.content?.parts?.[0]?.text) {\n                            return JSON.parse(data.candidates[0].content.parts[0].text);\n                        }\n                    } else if (apiUrl.includes('predict')) { \n                        if (data.predictions && data.predictions.length > 0) {\n                            return data;\n                        }\n                    }\n                    throw new Error(\"Respuesta inv\u00e1lida o vac\u00eda de la API.\");\n\n                } catch (error) {\n                    console.error(`Attempt ${i + 1} failed:`, error);\n                    if (i === retries - 1) throw error;\n                    await new Promise(resolve => setTimeout(resolve, delay * Math.pow(2, i)));\n                }\n            }\n        }\n        \n        function displaySeoResults(data) {\n            seoResultsWrapper.classList.remove('hidden');\n            imageGenerationSection.classList.add('hidden'); \n\n            if (data.focusKeyword) {\n                focusKeywordEl.textContent = data.focusKeyword;\n                focusKeywordSection.classList.remove('hidden');\n            }\n            if (data.secondaryKeywords && data.secondaryKeywords.length > 0) {\n                secondaryKeywordsListEl.innerHTML = data.secondaryKeywords.map(k => `<span class=\"bg-white text-gray-700 text-sm font-medium px-3 py-1 rounded-full shadow-sm\">${k}<\/span>`).join('');\n                secondaryKeywordsInputEl.value = data.secondaryKeywords.join(', ');\n                secondaryKeywordsSection.classList.remove('hidden');\n            }\n            if (data.seoDescription) {\n                seoDescriptionEl.textContent = data.seoDescription;\n                descriptionCharCountEl.textContent = `${data.seoDescription.length} caracteres`;\n                seoDescriptionSection.classList.remove('hidden');\n            }\n        }\n\n        function displayImageResults(data) {\n            imagesGrid.innerHTML = ''; \n            if (data.predictions && data.predictions.length > 0) {\n                data.predictions.forEach((prediction, index) => {\n                    const base64Data = prediction.bytesBase64Encoded;\n                    const imageUrl = `data:image\/png;base64,${base64Data}`;\n\n                    const imageCard = document.createElement('div');\n                    imageCard.className = \"bg-white rounded-lg shadow-md p-3 flex flex-col items-center\";\n                    imageCard.innerHTML = `\n                        <img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-orig-src=\"${imageUrl}\" alt=\"Imagen generada por IA ${index + 1}\" class=\"lazyload rounded-lg w-full h-48 object-cover mb-3\">\n                        <button onclick=\"downloadImage('${imageUrl}', 'imagen-articulo-${index + 1}.jpg')\" class=\"download-btn bg-purple-600 text-white font-bold py-2 px-4 rounded-xl hover:bg-purple-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-purple-500 transition-transform transform hover:scale-105 duration-200\">\n                            <i class=\"fas fa-download mr-2\"><\/i>Descargar\n                        <\/button>\n                    `;\n                    imagesGrid.appendChild(imageCard);\n                });\n                imageError.classList.add('hidden');\n            } else {\n                showImageError('No se recibieron im\u00e1genes de la IA.');\n            }\n        }\n\n        function downloadImage(imageUrl, filename) {\n            const canvas = document.createElement('canvas');\n            const context = canvas.getContext('2d');\n            canvas.width = 1024;\n            canvas.height = 1024;\n\n            const image = new Image();\n            image.onload = () => {\n                context.drawImage(image, 0, 0, 1024, 1024);\n                const dataURL = canvas.toDataURL('image\/jpeg', 0.9); \n                \n                const link = document.createElement('a');\n                link.href = dataURL;\n                link.download = filename;\n                document.body.appendChild(link);\n                link.click();\n                document.body.removeChild(link);\n            };\n            image.src = imageUrl;\n        }\n\n\n        function showImageError(message) {\n            imageError.textContent = message;\n            imageError.classList.remove('hidden');\n            imagesGrid.innerHTML = ''; \n        }\n\n        function showError(message) {\n            hideAllResults();\n            resultsContainer.classList.remove('hidden');\n            errorTextEl.textContent = message;\n            errorMessageEl.classList.remove('hidden');\n        }\n\n        function copyToClipboard(elementId) {\n            const element = document.getElementById(elementId);\n            const textToCopy = (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') ? element.value : element.textContent;\n            \n            const textarea = document.createElement('textarea');\n            textarea.value = textToCopy;\n            document.body.appendChild(textarea);\n            textarea.select();\n            try {\n                document.execCommand('copy');\n                showToast();\n            } catch (err) {\n                console.error('Fallback: Oops, unable to copy', err);\n            }\n            document.body.removeChild(textarea);\n        }\n\n        function showToast() {\n            const toast = document.getElementById('toast');\n            toast.classList.remove('opacity-0', 'translate-y-20');\n            toast.classList.add('opacity-100', 'translate-y-0');\n            setTimeout(() => {\n                toast.classList.add('opacity-0', 'translate-y-20');\n            }, 2000);\n        }\n    <\/script>\n<\/body>\n<\/html><\/div><\/div><\/div><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":2776,"menu_order":0,"comment_status":"open","ping_status":"closed","template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"portfolio_category":[53],"portfolio_skills":[],"portfolio_tags":[59,58],"class_list":["post-2769","avada_portfolio","type-avada_portfolio","status-publish","format-standard","has-post-thumbnail","hentry","portfolio_category-utilidades","portfolio_tags-marketing","portfolio_tags-utilidades-seo"],"acf":[],"_links":{"self":[{"href":"https:\/\/edukia.org\/ca\/wp-json\/wp\/v2\/avada_portfolio\/2769","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/edukia.org\/ca\/wp-json\/wp\/v2\/avada_portfolio"}],"about":[{"href":"https:\/\/edukia.org\/ca\/wp-json\/wp\/v2\/types\/avada_portfolio"}],"author":[{"embeddable":true,"href":"https:\/\/edukia.org\/ca\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/edukia.org\/ca\/wp-json\/wp\/v2\/comments?post=2769"}],"version-history":[{"count":7,"href":"https:\/\/edukia.org\/ca\/wp-json\/wp\/v2\/avada_portfolio\/2769\/revisions"}],"predecessor-version":[{"id":2777,"href":"https:\/\/edukia.org\/ca\/wp-json\/wp\/v2\/avada_portfolio\/2769\/revisions\/2777"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/edukia.org\/ca\/wp-json\/wp\/v2\/media\/2776"}],"wp:attachment":[{"href":"https:\/\/edukia.org\/ca\/wp-json\/wp\/v2\/media?parent=2769"}],"wp:term":[{"taxonomy":"portfolio_category","embeddable":true,"href":"https:\/\/edukia.org\/ca\/wp-json\/wp\/v2\/portfolio_category?post=2769"},{"taxonomy":"portfolio_skills","embeddable":true,"href":"https:\/\/edukia.org\/ca\/wp-json\/wp\/v2\/portfolio_skills?post=2769"},{"taxonomy":"portfolio_tags","embeddable":true,"href":"https:\/\/edukia.org\/ca\/wp-json\/wp\/v2\/portfolio_tags?post=2769"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}