{"id":73655,"date":"2024-02-14T19:16:46","date_gmt":"2024-02-14T18:16:46","guid":{"rendered":"https:\/\/kinsta.com\/es\/?p=73655&#038;preview=true&#038;preview_id=73655"},"modified":"2024-02-26T08:09:35","modified_gmt":"2024-02-26T07:09:35","slug":"actualizacion-masiva-de-plugins-wordpress","status":"publish","type":"post","link":"https:\/\/kinsta.com\/es\/blog\/actualizacion-masiva-de-plugins-wordpress\/","title":{"rendered":"Construye una herramienta para actualizar masivamente plugins de WordPress en varios sitios con la API de Kinsta"},"content":{"rendered":"<p>Los plugins desempe\u00f1an un papel vital en la personalizaci\u00f3n y mejora de tus sitios de WordPress. Se utilizan para a\u00f1adir funcionalidades como <a href=\"https:\/\/kinsta.com\/es\/blog\/plugins-formulario-contacto-wordpress\/\">formularios de contacto<\/a>, <a href=\"https:\/\/kinsta.com\/es\/blog\/plugins-de-ecommerce\/\">comercio electr\u00f3nico<\/a> y <a href=\"https:\/\/kinsta.com\/es\/secciones\/analiticas\/\">anal\u00edticas<\/a> a tus sitios sin necesidad de programaci\u00f3n.<\/p>\n<p>Al igual que WordPress, que recibe actualizaciones peri\u00f3dicas, los plugins tambi\u00e9n reciben actualizaciones peri\u00f3dicas para a\u00f1adir nuevas funciones, parchear un agujero de seguridad, aumentar la compatibilidad, etc. Por eso Kinsta incluy\u00f3 la <a href=\"https:\/\/kinsta.com\/es\/changelog\/actualiza-plugins-y-temas\/\">Administraci\u00f3n de Plugins y Temas<\/a> entre las herramientas disponibles en MyKinsta para cada uno de tus sitios.<\/p>\n<p>Sin embargo, la actualizaci\u00f3n de plugins en muchos sitios a\u00fan puede ser desalentadora para clientes ocupados como las agencias. Este art\u00edculo muestra una soluci\u00f3n que utiliza la <a href=\"https:\/\/kinsta.com\/es\/changelog\/api-kinsta\/\">API de Kinsta<\/a> para gestionar simult\u00e1neamente los plugins de varios sitios.<\/p>\n<div><\/div><kinsta-auto-toc heading=\"Table of Contents\" exclude=\"last\" list-style=\"arrow\" selector=\"h2\" count-number=\"-1\"><\/kinsta-auto-toc>\n<h2>Qu\u00e9 Est\u00e1s Construyendo<\/h2>\n<p>Esta gu\u00eda se centra en la construcci\u00f3n de una soluci\u00f3n avanzada utilizando la API de Kinsta, que ahora ofrece endpoints para recuperar y actualizar plugins.<\/p>\n<p>En ella, creamos una aplicaci\u00f3n React personalizada que obtiene todos los plugins de tu cuenta de empresa Kinsta. Esta herramienta te permite <strong>identificar y actualizar un plugin espec\u00edfico en m\u00faltiples sitios<\/strong>, agilizando el proceso significativamente.<\/p>\n<figure style=\"width: 1600px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/kinsta.com\/wp-content\/uploads\/2024\/02\/kinsta-plugin-manager.gif\" alt=\"Herramienta creada con React y la API de Kinsta para actualizar de forma masiva plugins de WordPress en m\u00faltiples sitios.\" width=\"1600\" height=\"225\"><figcaption class=\"wp-caption-text\">Herramienta creada con React y la API de Kinsta para actualizar de forma masiva plugins de WordPress en m\u00faltiples sitios.<\/figcaption><\/figure>\n<aside role=\"note\" class=\"wp-block-kinsta-notice is-style-info\">\n            <h3>Info<\/h3>\n        <p>Si eres una <a href=\"https:\/\/kinsta.com\/es\/directorio-de-agencias\/\">agencia<\/a> que gestiona varios sitios en Kinsta, puedes empezar a utilizar esta herramienta inmediatamente sin necesidad de profundizar en esta gu\u00eda, a menos que te interese comprender c\u00f3mo interact\u00faa con la API para a\u00f1adir funcionalidades personalizadas.<\/p>\n<p>Para utilizar esta herramienta, crea un repositorio <a href=\"https:\/\/kinsta.com\/es\/secciones\/git\/\">Git<\/a> <a href=\"https:\/\/github.com\/kinsta\/Kinsta-Plugin-Manager\" target=\"_blank\" rel=\"noopener noreferrer\">utilizando esta plantilla en GitHub<\/a>. Selecciona <strong>Utilizar esta plantilla <\/strong>&gt; <strong>Crear un nuevo repositorio<\/strong> para copiar el c\u00f3digo de inicio en un nuevo repositorio dentro de tu cuenta de GitHub.<\/p>\n<p>Una vez configurado tu repositorio, despli\u00e9galo gratuitamente en nuestra plataforma de alojamiento de sitios est\u00e1ticos y a\u00f1ade lo siguiente como <a href=\"https:\/\/kinsta.com\/es\/blog\/variables-de-entorno\/\">variables de entorno<\/a>:<\/p>\n<pre><code class=\"language-bash\">REACT_APP_KINSTA_COMPANY_ID = 'YOUR_COMPANY_ID' \nREACT_APP_KINSTA_API_KEY = 'YOUR_API_KEY'<\/code><\/pre>\n<p>Eso es todo. Ya puedes utilizar esta herramienta en tu empresa Kinsta para agilizar tus procesos de gesti\u00f3n de sitios.<\/p>\n<\/aside>\n\n<h2>Requisitos previos de la aplicaci\u00f3n<\/h2>\n<p>Para seguir este proyecto, debes tener lo siguiente:<\/p>\n<ul>\n<li>Conocimientos b\u00e1sicos de <a href=\"https:\/\/kinsta.com\/es\/blog\/que-es-el-html\/\">HTML<\/a>, <a href=\"https:\/\/kinsta.com\/es\/blog\/buenas-practicas-css\/\">CSS<\/a> y <a href=\"https:\/\/kinsta.com\/javascript\/\">JavaScript<\/a>.<\/li>\n<li>Cierta familiaridad con <a href=\"https:\/\/kinsta.com\/es\/blog\/que-es-react-js\/\">React<\/a>.<\/li>\n<li>Node.js y npm (<a href=\"https:\/\/kinsta.com\/es\/blog\/que-es-npm\/\">Node Package Manager<\/a>) o yarn instalados en tu ordenador.<\/li>\n<\/ul>\n<h2>Comprender la API de Kinsta<\/h2>\n<p>La <a href=\"https:\/\/kinsta.com\/es\/docs\/api-kinsta\/\">API de Kinsta<\/a> es una potente herramienta que te permite interactuar mediante programaci\u00f3n con los servicios de Kinsta, como los sitios alojados de WordPress. Puede ayudarte a automatizar varias tareas relacionadas con la gesti\u00f3n de WordPress, como la <a href=\"https:\/\/kinsta.com\/es\/blog\/api-wordpress\/\">creaci\u00f3n de sitios<\/a>, la <a href=\"https:\/\/kinsta.com\/es\/blog\/programar-tareas-api-kinsta\/\">recuperaci\u00f3n de informaci\u00f3n sobre sitios<\/a>, la <a href=\"https:\/\/kinsta.com\/es\/blog\/kinsta-api-key\/#how-to-use-kinsta-api-to-build-a-status-checker\">obtenci\u00f3n del estado de un sitio<\/a>, la <a href=\"https:\/\/kinsta.com\/es\/blog\/registros-del-servidor-api\/\">exploraci\u00f3n<\/a> y <a href=\"https:\/\/kinsta.com\/es\/blog\/copias-de-seguridad-wordpress-con-api-kinsta\/\">restauraci\u00f3n de copias de seguridad<\/a>, etc.<\/p>\n<p>Para utilizar la API de Kinsta, debes tener una cuenta con al menos un sitio, <a href=\"https:\/\/sevalla.com\/application-hosting\/\">aplicaci\u00f3n<\/a> o <a href=\"https:\/\/sevalla.com\/database-hosting\/\">base de datos<\/a> de WordPress en MyKinsta. Tambi\u00e9n debes generar una clave API para autenticarte y acceder a tu cuenta.<\/p>\n<p>Para generar una clave API:<\/p>\n<ol start=\"1\">\n<li>Ve a tu panel de <a href=\"https:\/\/my.kinsta.com\/?lang=es\" target=\"_blank\" rel=\"noopener noreferrer\">MyKinsta<\/a>.<\/li>\n<li>Ve a la p\u00e1gina <strong>Claves API <\/strong>(<strong>Tu nombre <\/strong>&gt;<strong> Configuraci\u00f3n de la empresa <\/strong>&gt;<strong> Claves API<\/strong>).<\/li>\n<li>Haz clic en <strong>Crear Clave API<\/strong>.<\/li>\n<li>Elige una fecha de caducidad o establece una fecha de inicio personalizada y un n\u00famero de horas para que caduque la clave.<\/li>\n<li>Dale a la clave un nombre \u00fanico.<\/li>\n<li>Haz clic en <strong>Generar<\/strong>.<\/li>\n<\/ol>\n<p>Despu\u00e9s de crear una clave API, c\u00f3piala y gu\u00e1rdala en un lugar seguro (se recomienda utilizar un <a href=\"https:\/\/kinsta.com\/es\/blog\/administradores-contrasenas\/\">gestor de contrase\u00f1as<\/a>). Puedes generar varias claves API, que aparecer\u00e1n en la p\u00e1gina <strong>Claves API<\/strong>. Si necesitas revocar una clave API, haz clic en el bot\u00f3n <strong>Revocar<\/strong>.<\/p>\n<h2>Configura tu entorno de desarrollo React<\/h2>\n<p>React es una <a href=\"https:\/\/kinsta.com\/es\/blog\/bibliotecas-javascript\/\">popular biblioteca JavaScript<\/a> para crear interfaces de usuario. Permite a los desarrolladores crear componentes declarativos que representan diferentes partes de la interfaz de usuario. Estos componentes se definen utilizando la <a href=\"https:\/\/kinsta.com\/es\/blog\/que-es-jsx\/\">sintaxis JSX<\/a>, una combinaci\u00f3n de JavaScript y HTML.<\/p>\n<p>Para empezar, sigue estos pasos:<\/p>\n<ol start=\"1\">\n<li>Navega hasta la carpeta en la que desees crear tu proyecto y utiliza <a href=\"https:\/\/reactjs.org\/docs\/create-a-new-react-app.html#create-react-app\" target=\"_blank\" rel=\"noopener noreferrer\">create-react-app<\/a> para crear un proyecto React:\n<pre><code class=\"language-bash\">npx create-react-app &lt;project-name&gt;<\/code><\/pre>\n<p>Cambia <code>&lt;project-name&gt;<\/code> por el nombre que prefieras para tu proyecto.<\/li>\n<li>Una vez hecho esto, navega hasta la carpeta del proyecto e inicia el servidor de desarrollo:\n<pre><code class=\"language-bash\">cd &lt;project-name&gt;\nnpm run start<\/code><\/pre>\n<p>Tu aplicaci\u00f3n React se abrir\u00e1 en tu navegador web predeterminado en http:\/\/localhost:3000.<\/li>\n<\/ol>\n<p>La creaci\u00f3n de un proyecto React mediante <code>create-react-app<\/code> establece una estructura de carpetas. La carpeta crucial es <strong>src<\/strong>, donde tiene lugar el desarrollo. Los archivos clave de esta carpeta son:<\/p>\n<ul>\n<li><strong>App.js:<\/strong> Este es el componente principal, que renderiza todos los dem\u00e1s en tu aplicaci\u00f3n React. Aqu\u00ed es donde se a\u00f1adir\u00e1 todo tu c\u00f3digo para esta herramienta.<\/li>\n<li><strong>index.js:<\/strong> Es el punto de entrada, se carga primero y es responsable de renderizar <strong>App.js<\/strong>.<\/li>\n<li><strong>index.css:<\/strong> Este archivo define el estilo y el dise\u00f1o general de tu aplicaci\u00f3n. Todos los estilos se a\u00f1adir\u00e1n aqu\u00ed.<\/li>\n<\/ul>\n<h2>Crear y estilizar la interfaz de usuario<\/h2>\n<p>Vamos a centrarnos en crear y estilizar la interfaz de una aplicaci\u00f3n b\u00e1sica alojada en el archivo <strong>App.js<\/strong> sin implicar enrutamiento. Nuestra interfaz de usuario principal es un formulario con un campo <code>select<\/code> para listar los plugins \u00fanicos de tus sitios Kinsta junto a un bot\u00f3n <code>submit<\/code> para buscar sitios con el plugin seleccionado.<\/p>\n<figure style=\"width: 1600px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/kinsta.com\/wp-content\/uploads\/2024\/02\/plugin-manager-ui.png\" alt=\"Interfaz de usuario de la herramienta de gesti\u00f3n de plugins para acceder a una lista de plugins y cargar sitios.\" width=\"1600\" height=\"225\"><figcaption class=\"wp-caption-text\">Interfaz de usuario de la herramienta de gesti\u00f3n de plugins para acceder a una lista de plugins y cargar sitios.<\/figcaption><\/figure>\n<p>Adem\u00e1s, una secci\u00f3n de visualizaci\u00f3n muestra detalles del sitio como el nombre, el estado del plugin y la versi\u00f3n. Incluye un bot\u00f3n para actualizar cada sitio si es necesario y un bot\u00f3n general para actualizar en bloque todos los sitios que requieran la actualizaci\u00f3n del plugin.<\/p>\n<p>En tu archivo <strong>App.js<\/strong>, a\u00f1ade el siguiente c\u00f3digo:<\/p>\n<pre><code class=\"language-jsx\">import KinstaLogo from '.\/images\/kinsta_logo.png';\n\nconst App = () =&gt; {\n    return (\n        &lt;div className=\"container\"&gt;\n            &lt;div className=\"title-section\"&gt;\n                &lt;img src={KinstaLogo} className=\"logo\" alt=\"\" \/&gt;\n                &lt;h2&gt;Manage your site's plugins&lt;\/h2&gt;\n                &lt;p&gt;\n                    Easily update plugins across all sites hosted with Kinsta using the\n                    Kinsta API.\n                &lt;\/p&gt;\n            &lt;\/div&gt;\n            &lt;div&gt; className=\"info-section\"&gt;\n                &lt;p&gt;\n                    This application allows you to retrieve a list of all sites within\n                    your company that uses a specific plugin. You can then choose to update\n                    the plugin across all these sites simultaneously or individually.\n                &lt;\/p&gt;\n            &lt;\/div&gt;\n            &lt;div className=\"form-section\"&gt;\n                &lt;form&gt;\n                    &lt;div className=\"form-control\"&gt;\n                        &lt;label&gt; htmlFor=\"plugin-name\"&gt;Plugin name&lt;\/label&gt;\n                        &lt;select name=\"plugin-name\" id=\"plugin-name\"&gt;\n                            &lt;option&gt; value=\"\"&gt;Select a plugin&lt;\/option&gt;\n                        &lt;\/select&gt;\n                    &lt;\/div&gt;\n                    &lt;button&gt; className=\"btn\"&gt;Fetch sites with this plugin&lt;\/button&gt;\n                &lt;\/form&gt;\n            &lt;\/div&gt;\n            &lt;div className=\"display_container\"&gt;\n                &lt;div className=\"site-list\"&gt;\n                    &lt;div className=\"list-title\"&gt;\n                        &lt;h3&gt;Sites with WooCommerce plugin&lt;\/h3&gt;\n\n                        &lt;button&gt; className=\"sm-btn\"&gt;Update all sites to v.3.6&lt;\/button&gt;\n                    &lt;\/div&gt;\n                    &lt;ul&gt;\n                        &lt;li&gt;\n                            &lt;div className=\"info\"&gt;\n                                &lt;p&gt;\n                                    &lt;b&gt;Site Name:&lt;\/b&gt; WooCommerce\n                                &lt;\/p&gt;\n                                &lt;p&gt;\n                                    &lt;b&gt;Plugin Status:&lt;\/b&gt; active\n                                &lt;\/p&gt;\n                                &lt;p&gt;\n                                    &lt;b&gt;Plugin Version:&lt;\/b&gt; 3.5.1\n                                &lt;\/p&gt;\n                            &lt;\/div&gt;\n                            &lt;button&gt; className=\"sm-btn\"&gt;Update to v.5.6&lt;\/button&gt;\n                        &lt;\/li&gt;\n                    &lt;\/ul&gt;\n                &lt;\/div&gt;\n            &lt;\/div&gt;\n        &lt;\/div&gt;\n    );\n};\n\nexport default App;<\/code><\/pre>\n<p>Para dar estilo a este proyecto, visita el <a href=\"https:\/\/github.com\/kinsta\/Kinsta-Plugin-Manager\/blob\/main\/src\/index.css\" target=\"_blank\" rel=\"noopener noreferrer\">archivo CSS en nuestro repositorio completo de GitHub<\/a> y copia su c\u00f3digo en tu archivo <strong>index.css<\/strong>.<\/p>\n<h2>Interactuar con la API de Kinsta<\/h2>\n<p>La API de Kinsta ofrece una serie de endpoints esenciales para acceder a diversos par\u00e1metros necesarios para interactuar con el plugin de un sitio. Por ejemplo, si deseas recuperar o actualizar un plugin, primero debes obtener el ID de entorno del sitio.<\/p>\n<p>Obtener este ID de entorno es un proceso secuencial. Inicialmente, debes determinar el ID del sitio. Para obtener el ID del sitio, debes tener el ID de tu empresa Kinsta. Este ID de empresa est\u00e1 disponible en tu panel de MyKinsta (<strong>Configuraci\u00f3n de la empresa<\/strong> &gt; <strong>Detalles de facturaci\u00f3n<\/strong>), y es informaci\u00f3n sensible que no querr\u00e1s compartir con nadie, como tu clave API.<\/p>\n<p>Puedes almacenarlos de forma segura como variables de entorno en tu aplicaci\u00f3n React creando un archivo <strong>.env<\/strong> en la carpeta ra\u00edz de tu proyecto. En este archivo, a\u00f1ade lo siguiente con el valor correcto:<\/p>\n<pre><code class=\"language-bash\">REACT_APP_KINSTA_COMPANY_ID = 'YOUR_COMPANY_ID' \nREACT_APP_KINSTA_API_KEY = 'YOUR_API_KEY'<\/code><\/pre>\n<p>Para acceder a estas variables de entorno dentro de tu proyecto, puedes utilizar la sintaxis <code>process.env.THE_VARIABLE<\/code>. Por ejemplo, para acceder a la <code>REACT_APP_KINSTA_COMPANY_ID<\/code>, utilizar\u00edas <code>process.env.REACT_APP_KINSTA_COMPANY_ID<\/code>.<\/p>\n<p>Si a\u00f1ades el archivo <strong>.env<\/strong> a tu archivo <strong><a href=\"https:\/\/kinsta.com\/es\/blog\/gitignore-no-funciona\/\">.gitignore<\/a><\/strong> es importante para evitar que se env\u00ede a GitHub. Esto garantiza que tu informaci\u00f3n sensible permanezca privada y segura.<\/p>\n<h3>Recuperar todos los sitios y plugins utilizando la API de Kinsta<\/h3>\n<p>Para recuperar los datos de los plugins de todos los sitios gestionados por tu cuenta de empresa Kinsta, puedes utilizar la API Kinsta ejecutando tres peticiones API. Aqu\u00ed tienes una explicaci\u00f3n simplificada:<\/p>\n<p>Comienza almacenando la URL de la API Kinsta en una variable para facilitar la consulta.<\/p>\n<pre><code class=\"language-js\">const KinstaAPIUrl = 'https:\/\/api.kinsta.com\/v2';<\/code><\/pre>\n<ol start=\"1\">\n<li><strong>Obtener la lista de sitios de la empresa:<\/strong> Necesitas obtener una lista de todos los sitios de WordPress asociados a tu empresa. Para ello, construye una consulta utilizando el ID de la empresa, realiza una solicitud GET con la autorizaci\u00f3n adecuada, procesa la respuesta en formato JSON y extrae los detalles del sitio de la respuesta.\n<pre><code class=\"language-js\">const query = new URLSearchParams({\n    company: process.env.REACT_APP_KINSTA_COMPANY_ID,\n}).toString();\nconst response = await fetch(`${KinstaAPIUrl}\/sites?${query}`, {\n    method: 'GET',\n    headers: { Authorization: `Bearer ${process.env.REACT_APP_KINSTA_API_KEY}` },\n});\n\nconst data = await response.json();\nconst companySites = data.company.sites;<\/code><\/pre>\n<\/li>\n<li><strong>Recuperar el ID del entorno del sitio:<\/strong> El paso anterior devuelve un array de sitios de WordPress. Para cada sitio, haz un bucle y otra petici\u00f3n GET para obtener los entornos asociados.\n<pre><code class=\"language-js\">const sitesEnvironmentData = companySites.map(async (site) =&gt; {\n    const siteId = site.id;\n    const resp = await fetch(`${KinstaAPIUrl}\/sites\/${siteId}\/environments`, {\n        method: 'GET',\n        headers: {\n            Authorization: `Bearer ${process.env.REACT_APP_KINSTA_API_KEY}`,\n        },\n    });\n    const data = await resp.json();\n    const environments = data.site.environments;\n    return {\n        id: siteId,\n        name: site.display_name,\n        environments: environments,\n    };\n});<\/code><\/pre>\n<\/li>\n<li><strong>Obtener la lista de plugins de sitios de WordPress:<\/strong> Tras obtener el ID del sitio, el nombre y el entorno, ahora puedes utilizar el ID del entorno para obtener una lista de todos los plugins de cada sitio. Primero tienes que resolver las promesas del paso anterior y luego hacer las peticiones GET para los plugins:\n<pre><code class=\"language-js\">\/\/ Wait for all the promises to resolve\nconst sitesData = await Promise.all(sitesEnvironmentData);\n\n\/\/ Get all plugins for each environment\nconst sitesWithPlugin = sitesData.map(async (site) =&gt; {\n    const environmentId = site.environments[0].id;\n    const resp = await fetch(\n        `${KinstaAPIUrl}\/sites\/environments\/${environmentId}\/plugins`,\n        {\n            method: 'GET',\n            headers: {\n                Authorization: `Bearer ${process.env.REACT_APP_KINSTA_API_KEY}`,\n            },\n        }\n    );\n    const data = await resp.json();\n    const plugins = data.environment.container_info;\n    return {\n        env_id: environmentId,\n        name: site.name,\n        plugins: plugins,\n    };\n});\n\nconst sitesWithPluginData = await Promise.all(sitesWithPlugin);\nreturn sitesWithPluginData;<\/code><\/pre>\n<\/li>\n<li><strong>Consolidando el proceso:<\/strong> Para agilizar el proceso, puedes encapsular estas peticiones a la API en una \u00fanica funci\u00f3n as\u00edncrona <code>getSitesWithPluginData<\/code>, que puede reutilizarse. Esta funci\u00f3n ejecutar\u00e1 los pasos descritos anteriormente y devolver\u00e1 un array con la informaci\u00f3n esencial sobre cada sitio, incluyendo el ID del entorno, el nombre del sitio y un array de plugins.\n<pre><code class=\"language-jsx\">const getSitesWithPluginData = async () =&gt; {\n    const query = new URLSearchParams({\n        company: process.env.REACT_APP_KINSTA_COMPANY_ID,\n    }).toString();\n    const resp = await fetch(`${KinstaAPIUrl}\/sites?${query}`, {\n        method: 'GET',\n        headers: {\n            Authorization: `Bearer ${process.env.REACT_APP_KINSTA_API_KEY}`,\n        },\n    });\n\n    const data = await resp.json();\n    const companySites = data.company.sites;\n\n    \/\/ Get all environments for each site\n    const sitesEnvironmentData = companySites.map(async (site) =&gt; {\n        const siteId = site.id;\n        const resp = await fetch(`${KinstaAPIUrl}\/sites\/${siteId}\/environments`, {\n            method: 'GET',\n            headers: {\n                Authorization: `Bearer ${process.env.REACT_APP_KINSTA_API_KEY}`,\n            },\n        });\n        const data = await resp.json();\n        const environments = data.site.environments;\n        return {\n            id: siteId,\n            name: site.display_name,\n            environments: environments,\n        };\n    });\n\n    \/\/ Wait for all the promises to resolve\n    const sitesData = await Promise.all(sitesEnvironmentData);\n\n    \/\/ Get all plugins for each environment\n    const sitesWithPlugin = sitesData.map(async (site) =&gt; {\n        const environmentId = site.environments[0].id;\n        const resp = await fetch(\n            `${KinstaAPIUrl}\/sites\/environments\/${environmentId}\/plugins`,\n            {\n                method: 'GET',\n                headers: {\n                    Authorization: `Bearer ${process.env.REACT_APP_KINSTA_API_KEY}`,\n                },\n            }\n        );\n        const data = await resp.json();\n        const plugins = data.environment.container_info;\n        return {\n            env_id: environmentId,\n            name: site.name,\n            plugins: plugins,\n        };\n    });\n\n    \/\/ Wait for all the promises to resolve\n    const sitesWithPluginData = await Promise.all(sitesWithPlugin);\n    return sitesWithPluginData;\n};<\/code><\/pre>\n<\/li>\n<\/ol>\n<h3>Recuperar plugins \u00fanicos de todos los sitios<\/h3>\n<p>En tu aplicaci\u00f3n, quieres mostrar la lista de plugins de todos los sitios en un men\u00fa desplegable <code>select<\/code>. Para conseguirlo, la funci\u00f3n <code>getSitesWithPluginData<\/code> recupera el ID de entorno, el nombre y los plugins de cada sitio. Estos datos constituyen la base para extraer una lista de plugins.<\/p>\n<p>Define una nueva funci\u00f3n, <code>fetchAllSitesPlugins<\/code>que llame a <code>getSitesWithPluginData<\/code> y procese su salida para obtener una lista de todos los plugins:<\/p>\n<pre><code class=\"language-js\">const fetchAllSitesPlugins = async () =&gt; {\n    const sitesWithPluginData = await getSitesWithPluginData();\n\n    \/\/ get all plugins\n    const allPlugins = sitesWithPluginData.map((site) =&gt; {\n        const { plugins } = site;\n        return plugins.wp_plugins.data;\n    });\n\n   \/\/ \u2026\n};<\/code><\/pre>\n<p>Este c\u00f3digo itera sobre los datos de cada sitio y compila una lista de plugins. Para asegurarte de que cada plugin se enumera s\u00f3lo una vez, utiliza el objeto JavaScript <code>Set<\/code>, que almacena valores \u00fanicos:<\/p>\n<pre><code class=\"language-js\">\/\/ get unique plugins\n    const uniquePlugins = [\n        ...new Set(allPlugins.flat().map((plugin) =&gt; plugin.name)),\n    ];<\/code><\/pre>\n<p>El m\u00e9todo <code>.flat()<\/code> aplana la estructura del array y <code>.map()<\/code> la recorre para extraer s\u00f3lo los nombres de los plugins. El objeto <code>Set<\/code> filtra los duplicados.<\/p>\n<p>Para cargar y mostrar estos datos en tu aplicaci\u00f3n React, utiliza los hooks <code>useState()<\/code> y <code>useEffect()<\/code>:<\/p>\n<pre><code class=\"language-jsx\">import { useState, useEffect } from 'react';\n\nconst App = () =&gt; {\n    const [pluginName, setPluginName] = useState('');\n    const [plugins, setPlugins] = useState([]);\n\n    \/\/Get sites with plugin data\n    const getSitesWithPluginData = async () =&gt; {\n        \/\/ perform requests\n    };\n\n    useEffect(() =&gt; {\n        const fetchAllSitesPlugins = async () =&gt; {\n            const sitesWithPluginData = await getSitesWithPluginData();\n            \/\/ get all plugins\n            const allPlugins = sitesWithPluginData.map((site) =&gt; {\n                const { plugins } = site;\n                return plugins.wp_plugins.data;\n            });\n            \/\/ get unique plugins\n            const uniquePlugins = [\n                ...new Set(allPlugins.flat().map((plugin) =&gt; plugin.name)),\n            ];\n            setPlugins(uniquePlugins);\n        };\n\n        fetchAllSitesPlugins();\n    }, []);\n\n     \/\/ JSX render code follows\n    \/\/...\n};<\/code><\/pre>\n<p>El hook <code>useEffect()<\/code> garantiza que los datos se obtienen y se establecen cuando se monta el componente. El hook <code>useState()<\/code> mantiene la lista de plugins \u00fanicos.<\/p>\n<p>Por \u00faltimo, muestra estos plugins en un campo <code>select<\/code>. Si los plugins a\u00fan se est\u00e1n cargando, muestra un mensaje de marcador de posici\u00f3n:<\/p>\n<pre><code class=\"language-jsx\">&lt;select&gt;\n    name=\"plugin-name\"\n    id=\"plugin-name\"\n    value={pluginName}\n    onChange={(e) =&gt; setPluginName(e.target.value)}\n&gt;\n    {plugins.length &gt; 0 ? (\n        &lt;&gt;\n            &lt;option value=\"\"&gt;Select a plugin&lt;\/option&gt;\n            {plugins.map((plugin) =&gt; (\n                &lt;option key={plugin} value={plugin.toLowerCase()}&gt;\n                    {plugin}\n                &lt;\/option&gt;\n            ))}\n        &lt;\/&gt;\n    ) : (\n        &lt;option&gt; value=\"\"&gt;Loading plugins...&lt;\/option&gt;\n    )}\n&lt;\/select&gt;<\/code><\/pre>\n<p>En este c\u00f3digo:<\/p>\n<ul>\n<li>El elemento <code>select<\/code> est\u00e1 vinculado a una variable de estado <code>pluginName<\/code> para almacenar el valor seleccionado.<\/li>\n<li>El manejador <code>onChange<\/code> actualiza este estado cada vez que se selecciona un nuevo plugin.<\/li>\n<li>La funci\u00f3n <code>plugins.map()<\/code> crea din\u00e1micamente elementos de opci\u00f3n para cada plugin.<\/li>\n<\/ul>\n<p>Siguiendo estos pasos, tu aplicaci\u00f3n mostrar\u00e1 efectivamente una lista \u00fanica de plugins obtenidos de todos los sitios, proporcionando una interfaz limpia y f\u00e1cil de usar para la selecci\u00f3n.<\/p>\n<figure style=\"width: 1600px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/kinsta.com\/wp-content\/uploads\/2024\/02\/select-field-plugin-manager.png\" alt=\"Selecciona el campo que muestra la lista de plugins \u00fanicos de todos los sitios de la cuenta de empresa Kinsta.\" width=\"1600\" height=\"225\"><figcaption class=\"wp-caption-text\">Selecciona el campo que muestra la lista de plugins \u00fanicos de todos los sitios de la cuenta de empresa Kinsta.<\/figcaption><\/figure>\n<h3>Obtener sitios con un plugin espec\u00edfico<\/h3>\n<p>Hasta ahora, has podido recuperar plugins de tu cuenta de empresa Kinsta, pero quieres hacer un bucle por todos los sitios para recuperar sitios con un plugin concreto, almacenarlos en un estado y luego mostrarlos.<\/p>\n<p>Para ello, crea dos estados: uno para almacenar los sitios (<code>sites<\/code>) y otro para indicar el estado de carga (<code>isLoading<\/code>).<\/p>\n<pre><code class=\"language-jsx\">const [sites, setSites] = useState([]);\nconst [isLoading, setIsLoading] = useState(false);<\/code><\/pre>\n<p>A continuaci\u00f3n, crea una funci\u00f3n <code>fetchSites<\/code> para filtrar cada sitio y comprobar si contiene el plugin seleccionado. Si lo contiene, se almacenan los detalles relevantes del sitio.<\/p>\n<p>Esta funci\u00f3n comienza estableciendo <code>isLoading<\/code> en <code>true<\/code> y borrando el array <code>sites<\/code>. A continuaci\u00f3n, llama a <code>getSitesWithPluginData<\/code> para obtener todos los datos del sitio.<\/p>\n<pre><code class=\"language-jsx\">const fetchSites = async () =&gt; {\n    setIsLoading(true);\n    setSites([]);\n    const sitesWithPluginData = await getSitesWithPluginData();\n\n    \/\/ Filter out sites that don't have the plugin\n    const sitesWithPluginDataFiltered = sitesWithPluginData\n        .filter((site) =&gt; {\n            const sitePlugins = site.plugins.wp_plugins.data;\n            return sitePlugins.some((plugin) =&gt; {\n                return plugin.name === pluginName;\n            });\n        })\n        .map((site) =&gt; {\n            const { env_id, name } = site;\n            const { version, status, update, update_version } =\n                site.plugins.wp_plugins.data.find(\n                    (plugin) =&gt; plugin.name === pluginName\n                );\n            return {\n                env_id,\n                name,\n                version,\n                status,\n                updateAvailable: update,\n                updateVersion: update_version,\n            };\n        });\n    setSites(sitesWithPluginDataFiltered);\n    setIsLoading(false);\n};<\/code><\/pre>\n<p>En la funci\u00f3n <code>sitesWithPluginDataFiltered<\/code>:<\/p>\n<ul>\n<li>El m\u00e9todo <code>.filter()<\/code> a\u00edsla los sitios que contienen el plugin seleccionado.<\/li>\n<li>A continuaci\u00f3n, el m\u00e9todo <code>.map()<\/code> extrae los datos necesarios de cada sitio.<\/li>\n<li>Por \u00faltimo, los hooks <code>setSites<\/code> y <code>setIsLoading<\/code> actualizan el estado con los nuevos datos y el estado de carga.<\/li>\n<\/ul>\n<p>A continuaci\u00f3n, crea una funci\u00f3n <code>handleSubmit<\/code> y a\u00f1\u00e1dela al bot\u00f3n <strong>Obtener sitios con este plugin<\/strong> del formulario para invocar la funci\u00f3n cuando un usuario seleccione un plugin y env\u00ede el formulario. Esta funci\u00f3n evita la acci\u00f3n por defecto del formulario y llama a <code>fetchSites<\/code>:<\/p>\n<pre><code class=\"language-jsx\">const handleSubmit = (e) =&gt; {\n    e.preventDefault();\n    fetchSites();\n};<\/code><\/pre>\n<p>De este modo, cuando un usuario selecciona un plugin concreto y pulsa el bot\u00f3n de env\u00edo, obtiene todos los sitios con ese plugin y los almacena en el estado <code>sites<\/code>.<\/p>\n<h4>Mostrar los sitios con el plugin seleccionado<\/h4>\n<p>Una vez almacenados con \u00e9xito los sitios relevantes en tu estado <code>sites<\/code>, el siguiente paso es mostrar estos datos en la interfaz de usuario de tu proyecto. El objetivo es presentar cada sitio como un elemento de la lista con detalles clave y un bot\u00f3n condicional para actualizar el plugin.<\/p>\n<pre><code class=\"language-jsx\">&lt;ul&gt;\n    {sites.map((site) =&gt; (\n        &lt;li key={site.env_id}&gt;\n            &lt;div className=\"info\"&gt;\n                &lt;p&gt;\n                    &lt;b&gt;Site Name:&lt;\/b&gt; {site.name}\n                &lt;\/p&gt;\n                &lt;p&gt;\n                    &lt;b&gt;Plugin Status:&lt;\/b&gt; {site.status}\n                &lt;\/p&gt;\n                &lt;p&gt;\n                    &lt;b&gt;Plugin Version:&lt;\/b&gt; {site.version}\n                &lt;\/p&gt;\n            &lt;\/div&gt;\n            &lt;button&gt;\n                className={`sm-btn ${\n                    site.updateAvailable !== 'available' ? 'disabled-btn' : ''\n                }`}\n                disabled={site.updateAvailable !== 'available'}\n            &gt;\n                {site.updateAvailable === 'available'\n                    ? `Update to v.${site.updateVersion}`\n                    : 'Up to date'}\n            &lt;\/button&gt;\n        &lt;\/li&gt;\n    ))}\n&lt;\/ul&gt;<\/code><\/pre>\n<p>En el c\u00f3digo anterior, se itera sobre la array <code>sites<\/code> utilizando el m\u00e9todo <code>.map()<\/code>, creando una lista (<code>&lt;ul&gt;<\/code>) de sitios (<code>&lt;li&gt;<\/code> elementos). Cada elemento de la lista contiene detalles sobre el sitio y un bot\u00f3n para actualizar el plugin.<\/p>\n<p>El bot\u00f3n de la Interfaz de Usuario cambia de estilo y funci\u00f3n en funci\u00f3n del estado de actualizaci\u00f3n del plugin: est\u00e1 activo para las actualizaciones disponibles, de lo contrario est\u00e1 desactivado y etiquetado como \u00abUp to date\u00bb (Actualizado), controlado por <a href=\"https:\/\/kinsta.com\/es\/blog\/buenas-practicas-css\/\">CSS<\/a> condicional y el atributo disabled (desactivado).<\/p>\n<p>Adem\u00e1s, para mejorar la experiencia del usuario, vamos a a\u00f1adir un texto de carga de forma condicional utilizando el estado <code>isLoading<\/code> cuando se est\u00e1n obteniendo los sitios.<\/p>\n<pre><code class=\"language-jsx\">{isLoading && (\n    &lt;div className=\"loading\"&gt;\n        &lt;p&gt;Loading...&lt;\/p&gt;\n    &lt;\/div&gt;\n)}<\/code><\/pre>\n<figure style=\"width: 1600px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/kinsta.com\/wp-content\/uploads\/2024\/02\/list-sites-plugin.png\" alt=\"Una lista de sitios que utilizan un determinado plugin de la cuenta de empresa de Kinsta con botones para actualizarlos individualmente o a la vez.\" width=\"1600\" height=\"225\"><figcaption class=\"wp-caption-text\">Una lista de sitios que utilizan un determinado plugin de la cuenta de empresa de Kinsta con botones para actualizarlos individualmente o a la vez.<\/figcaption><\/figure>\n<h3>Actualizar plugins con la API de Kinsta<\/h3>\n<p>Hasta ahora, hemos podido obtener sitios con detalles importantes y acceder a sus plugins. El objetivo de esta herramienta es facilitar la actualizaci\u00f3n de plugins en varios sitios utilizando la API de Kinsta. El proceso implica iniciar actualizaciones y seguir su progreso.<\/p>\n<h4>Activaci\u00f3n de actualizaciones de plugins<\/h4>\n<p>Se proporciona un bot\u00f3n para cada sitio de la lista. Est\u00e1 dise\u00f1ado para reflejar si hay una actualizaci\u00f3n disponible. Si hay una actualizaci\u00f3n disponible, al hacer clic en el bot\u00f3n se activa la funci\u00f3n <code>updatePlugin<\/code>.<\/p>\n<pre><code class=\"language-jsx\">&lt;button&gt;\n    className={`sm-btn ${\n        site.updateAvailable !== 'available' ? 'disabled-btn' : ''\n    }`}\n    disabled={site.updateAvailable !== 'available'}\n    onClick={() =&gt;\n        updatePlugin(site.env_id, site.updateVersion)\n    }\n&gt;\n    {site.updateAvailable === 'available'\n        ? `Update to v.${site.updateVersion}`\n        : 'Up to date'}\n&lt;\/button&gt;<\/code><\/pre>\n<p>El manejador <code>onClick<\/code> llama a <code>updatePlugin<\/code> con el ID de entorno del sitio y la \u00faltima versi\u00f3n del plugin (<code>updateVersion<\/code>). Esta funci\u00f3n env\u00eda una solicitud PUT a la API de Kinsta para actualizar el plugin.<\/p>\n<pre><code class=\"language-jsx\">const updatePlugin = async (envId, pluginVersion) =&gt; {\n    const resp = await fetch(`${KinstaAPIUrl}\/sites\/environments\/${envId}\/plugins`, {\n        method: 'PUT',\n        headers: {\n            'Content-Type': 'application\/json',\n            Authorization: `Bearer ${process.env.REACT_APP_KINSTA_API_KEY}`,\n        },\n        body: JSON.stringify({\n            name: pluginName,\n            update_version: pluginVersion,\n        }),\n    });\n\n    const data = await resp.json();\n    \/\/ Further processing\n};<\/code><\/pre>\n<h4>Seguir el progreso de la actualizaci\u00f3n<\/h4>\n<p>Despu\u00e9s de iniciar la actualizaci\u00f3n, tienes que controlar su progreso. La API Kinsta proporciona una respuesta como \u00e9sta al iniciar una actualizaci\u00f3n:<\/p>\n<pre><code class=\"language-jsx\">{\n  \"operation_id\": \"wp-plugin:update-54fb80af-576c-4fdc-ba4f-b596c83f15a1\",\n  \"message\": \"Updating WordPress plugin in progress\",\n  \"status\": 202\n}<\/code><\/pre>\n<p><code>operation_id<\/code> realiza un seguimiento del estado de la actualizaci\u00f3n a trav\u00e9s del endpoint de operaciones. Crea una funci\u00f3n para hacer esta petici\u00f3n a la API, esperando el <code>operation_id<\/code> como argumento:<\/p>\n<pre><code class=\"language-jsx\">\/\/ Check plugin update status\nconst checkPluginUpdateStatus = async (operationId) =&gt; {\n    const resp = await fetch(`${KinstaAPIUrl}\/operations\/${operationId}`, {\n        method: 'GET',\n        headers: {\n            Authorization: `Bearer ${process.env.REACT_APP_KINSTA_API_KEY}`,\n        },\n    });\n    const data = await resp.json();\n    return data.status;\n};<\/code><\/pre>\n<p>Dentro de <code>updatePlugin<\/code>, utiliza una sentencia <code>if<\/code> para comprobar si la solicitud de actualizaci\u00f3n inicial <code>status<\/code> es <code>202<\/code>. Si es as\u00ed, establece un intervalo para llamar a <code>checkPluginUpdateStatus<\/code> cada cinco segundos (5000 milisegundos).<\/p>\n<p>El intervalo comprueba repetidamente el estado de la actualizaci\u00f3n y, si tiene \u00e9xito, borra el intervalo y llama a <code>fetchSites<\/code> para actualizar la lista de sitios. Si se produce un error durante estas comprobaciones, se registra en la consola.<\/p>\n<pre><code class=\"language-jsx\">if (data.status === 202) {\n    const interval = setInterval(() =&gt; {\n        checkPluginUpdateStatus(data.operation_id)\n            .then((status) =&gt; {\n                console.log(status);\n                if (status === 200) {\n                    clearInterval(interval);\n                    fetchSites();\n                }\n            })\n            .catch((error) =&gt; {\n                \/\/ Handle any errors that occur during the promise resolution\n                console.error('Error:', error);\n            });\n    }, 5000);\n}<\/code><\/pre>\n<h4>Respuesta del usuario durante el funcionamiento<\/h4>\n<p>En este punto todo funciona bien, pero es bueno hacer que el usuario sea consciente del progreso de la operaci\u00f3n en lugar de dejar que lo adivine. Puedes hacerlo mostrando una notificaci\u00f3n que aparezca cuando la operaci\u00f3n est\u00e9 en curso y se borre cuando haya terminado. Crea un estado <code>showStatusBar<\/code> para controlar esto:<\/p>\n<pre><code class=\"language-jsx\">const [showStatusBar, setShowStatusBar] = useState(false);<\/code><\/pre>\n<p>Cuando <code>showStatusBar<\/code> es <code>true<\/code>, aparece una barra de estado en la parte superior de la pantalla, indicando que hay una actualizaci\u00f3n en curso. Su estilo es fijo en la parte superior de la pantalla.<\/p>\n<pre><code class=\"language-jsx\">{showStatusBar && (\n    &lt;div className=\"status-bar\"&gt;\n        &lt;p&gt;Updating WordPress plugin in progress...&lt;\/p&gt;\n    &lt;\/div&gt;\n)}<\/code><\/pre>\n<p>Ahora puedes ajustar la sentencia <code>if<\/code> en la funci\u00f3n <code>updatePlugin<\/code> para establecer <code>showStatusBar<\/code> en <code>true<\/code> o <code>false<\/code> en funci\u00f3n del estado de actualizaci\u00f3n:<\/p>\n<pre><code class=\"language-jsx\">if (data.status === 202) {\n    setShowStatusBar(true);\n    const interval = setInterval(() =&gt; {\n        checkPluginUpdateStatus(data.operation_id)\n            .then((status) =&gt; {\n                console.log(status);\n                if (status === 200) {\n                    setShowStatusBar(false);\n                    clearInterval(interval);\n                    fetchSites();\n                }\n            })\n            .catch((error) =&gt; {\n                \/\/ Handle any errors that occur during the promise resolution\n                console.error('Error:', error);\n            });\n    }, 5000);\n}<\/code><\/pre>\n<p>Este enfoque garantiza que los usuarios est\u00e9n informados sobre el estado de las actualizaciones de los plugins, mejorando la usabilidad general de la herramienta.<\/p>\n<h3>Actualizar plugins en varios sitios con la API de Kinsta<\/h3>\n<p>La principal caracter\u00edstica de esta herramienta es la posibilidad de actualizar un plugin concreto con un solo clic en varios sitios dentro de tu cuenta Kinsta. Esto es similar a la funcionalidad implementada para actualizar plugins en un solo sitio.<\/p>\n<p>El proceso implica un bucle a trav\u00e9s del estado <code>sites<\/code>, que contiene los sitios con el plugin concreto que necesita una actualizaci\u00f3n. Para cada sitio que requiera una actualizaci\u00f3n, se realiza una solicitud a la API para actualizar el plugin y, posteriormente, se realiza un seguimiento del estado de la operaci\u00f3n:<\/p>\n<pre><code class=\"language-jsx\">\/\/ Update all plugins\nconst updateAllPlugins = async () =&gt; {\n    sites.map(async (site) =&gt; {\n        if (site.updateAvailable === 'available') {\n            const environmentId = site.env_id;\n            const resp = await fetch(\n                `${KinstaAPIUrl}\/sites\/environments\/${environmentId}\/plugins`,\n                {\n                    method: 'PUT',\n                    headers: {\n                        'Content-Type': 'application\/json',\n                        Authorization: `Bearer ${process.env.REACT_APP_KINSTA_API_KEY}`,\n                    },\n                    body: JSON.stringify({\n                        name: pluginName,\n                        update_version: site.updateVersion,\n                    }),\n                }\n            );\n            const data = await resp.json();\n            if (data.status === 202) {\n                setShowStatusBar(true);\n                const interval = setInterval(() =&gt; {\n                    checkPluginUpdateStatus(data.operation_id)\n                        .then((status) =&gt; {\n                            console.log(status);\n                            if (status === 200) {\n                                setShowStatusBar(false);\n                                clearInterval(interval);\n                                fetchSites();\n                            }\n                        })\n                        .catch((error) =&gt; {\n                            \/\/ Handle any errors that occur during the promise resolution\n                            console.error('Error:', error);\n                        });\n                }, 5000);\n            }\n        }\n    });\n};<\/code><\/pre>\n<p>Esta funci\u00f3n est\u00e1 conectada a un bot\u00f3n <strong>Actualizar Todo<\/strong>. Para mejorar la experiencia del usuario, el bot\u00f3n muestra el n\u00famero de versi\u00f3n al que se est\u00e1n actualizando los plugins:<\/p>\n<pre><code class=\"language-jsx\">&lt;button&gt; className=\"sm-btn\" onClick={updateAllPlugins}&gt;\n    Update all sites to v.\n    {\n        sites.find((site) =&gt; site.updateVersion !== null)\n            ?.updateVersion\n    }\n&lt;\/button&gt;<\/code><\/pre>\n<p>Adem\u00e1s, renderizamos condicionalmente este bot\u00f3n para que s\u00f3lo aparezca cuando m\u00e1s de un sitio requiera una actualizaci\u00f3n del plugin. Si todos los sitios est\u00e1n actualizados, en su lugar se muestra un mensaje:<\/p>\n<pre><code class=\"language-jsx\">&lt;div className=\"list-title\"&gt;\n    &lt;h3&gt;Sites with {pluginName} plugin&lt;\/h3&gt;\n    {sites.filter((site) =&gt; site.updateAvailable === 'available')\n        .length &gt; 1 && (\n        &lt;button className=\"sm-btn\" onClick={updateAllPlugins}&gt;\n            Update all sites to v.\n            {\n                sites.find((site) =&gt; site.updateVersion !== null)\n                    ?.updateVersion\n            }\n        &lt;\/button&gt;\n    )}\n    {sites.every((site) =&gt; site.updateAvailable !== 'available') && (\n        &lt;p&gt;All sites are up to date&lt;\/p&gt;\n    )}\n&lt;\/div&gt;<\/code><\/pre>\n<p>Con estas implementaciones, ahora puedes actualizar plugins sin esfuerzo en m\u00faltiples sitios de tu cuenta Kinsta, mejorando la eficiencia y asegur\u00e1ndote de que todos tus sitios est\u00e1n actualizados con las \u00faltimas versiones de plugins.<\/p>\n<h2>Despliega gratis tu sitio est\u00e1tico React en Kinsta<\/h2>\n<p>Estamos utilizando el <a href=\"https:\/\/sevalla.com\/static-site-hosting\/\">alojamiento de sitios est\u00e1ticos de Kinsta<\/a> para mostrar la aplicaci\u00f3n. En la pr\u00e1ctica, podr\u00edas ejecutar esta aplicaci\u00f3n React desde tu propia red o desplegarla s\u00f3lo despu\u00e9s de a\u00f1adir un medio de autenticaci\u00f3n a esta herramienta por seguridad.<\/p>\n<p>Puedes alojar tus aplicaciones React creadas con <code>create-react-app<\/code> como un sitio est\u00e1tico utilizando nuestro alojamiento de sitios est\u00e1ticos de forma gratuita enviando tu c\u00f3digo a un proveedor Git preferido (<a href=\"https:\/\/docs.sevalla.com\/applications\/git\/bitbucket#grant-access-to-the-kinsta-bitbucket-application\">Bitbucket<\/a>, <a href=\"https:\/\/docs.sevalla.com\/applications\/git\/github#authenticate-and-authorize\">GitHub<\/a> o <a href=\"https:\/\/docs.sevalla.com\/applications\/git\/gitlab#authorize-the-kinsta-gitlab-application\">GitLab<\/a>).<\/p>\n<p>Una vez que tu repositorio est\u00e9 listo, sigue estos pasos para desplegar tu sitio est\u00e1tico en Kinsta:<\/p>\n<ol start=\"1\">\n<li>Inicia sesi\u00f3n o crea una cuenta para ver tu panel <a href=\"https:\/\/my.kinsta.com\/?lang=es\" target=\"_blank\" rel=\"noopener noreferrer\">MyKinsta<\/a>.<\/li>\n<li>Autoriza a Kinsta con tu proveedor de Git.<\/li>\n<li>Haz clic en <strong>Sitios Est\u00e1ticos<\/strong> en la barra lateral izquierda, y luego en <strong>A\u00f1adir sitio<\/strong>.<\/li>\n<li>Selecciona el repositorio y la rama desde la que deseas desplegar.<\/li>\n<li>Asigna un nombre \u00fanico a tu sitio.<\/li>\n<li>A\u00f1ade la configuraci\u00f3n de construcci\u00f3n en el siguiente formato:\n<ul>\n<li><strong>Comando de construcci\u00f3n:<\/strong> npm run build<\/li>\n<li><strong>Versi\u00f3n de Node<\/strong>: 18.16.0<\/li>\n<li><strong>Directorio de publicaci\u00f3n<\/strong>: build<\/li>\n<\/ul>\n<\/li>\n<li>Por \u00faltimo, haz clic en <strong>Crear sitio<\/strong>.<\/li>\n<\/ol>\n<p>\u00a1Y ya est\u00e1! En pocos segundos tendr\u00e1s un sitio desplegado. Se proporciona un enlace para acceder a la versi\u00f3n desplegada de tu sitio. Si lo deseas, puedes a\u00f1adir m\u00e1s adelante tu <a href=\"https:\/\/docs.sevalla.com\/applications\/domains\">dominio personalizado<\/a> y tu <a href=\"https:\/\/docs.sevalla.com\/applications\/domains#install-a-custom-ssl-certificate\">certificado SSL<\/a>.<\/p>\n<p>Como alternativa al alojamiento de sitios est\u00e1ticos, puedes desplegar tu sitio est\u00e1tico con el <a href=\"https:\/\/sevalla.com\/application-hosting\/\">alojamiento de aplicaciones<\/a> de Kinsta, que proporciona una mayor flexibilidad de alojamiento, una gama m\u00e1s amplia de ventajas y acceso a funciones m\u00e1s robustas. Por ejemplo, escalabilidad, despliegue personalizado mediante un Dockerfile, y <a href=\"https:\/\/docs.sevalla.com\/applications\/analytics\">anal\u00edticas completas<\/a> que abarcan datos hist\u00f3ricos y en tiempo real.<\/p>\n<h2>Resumen<\/h2>\n<p>La API de Kinsta abre posibilidades m\u00e1s all\u00e1 de lo que hemos comentado. Una aplicaci\u00f3n interesante podr\u00eda ser la <a href=\"https:\/\/kinsta.com\/es\/blog\/construir-slackbot-para-gestion-de-sitios\/\">creaci\u00f3n de un Slackbot<\/a> que te notifique en Slack cada vez que alg\u00fan plugin est\u00e9 desactualizado. Esta integraci\u00f3n puede agilizar significativamente tu flujo de trabajo, manteni\u00e9ndote informado y proactivo.<\/p>\n<p>Tambi\u00e9n puedes desarrollar una herramienta similar, como se explica en esta gu\u00eda, para <a href=\"https:\/\/api-docs.kinsta.com\/tag\/WordPress-Site-Themes-and-Plugins#operation\/updateTheme\" target=\"_blank\" rel=\"noopener noreferrer\">actualizar tus temas<\/a>, ya que la API de Kinsta ya dispone de endpoints para ello.<\/p>\n<p>El equipo de Kinsta trabaja constantemente para a\u00f1adir las pr\u00f3ximas funciones siguiendo de cerca y escuchando los comentarios, como comparte Kristof Siket, jefe del equipo de desarrollo de la API de Kinsta:<\/p>\n<blockquote><p><em>Los comentarios de los usuarios impulsan la priorizaci\u00f3n de las funciones expuestas. El plan actual no cubre completamente la p\u00e1gina de Herramientas; en su lugar, las caracter\u00edsticas se basan en las peticiones de los usuarios y en los comentarios recogidos. Si crees que una herramienta o endpoint espec\u00edfico deber\u00eda incluirse en la API Kinsta, no dudes en <a href=\"https:\/\/kinsta.com\/es\/docs\/servicio-de-informacion\/programa-de-investigacion-kinsta\/#how-to-join\">enviar tus comentarios<\/a>.<\/em><\/p><\/blockquote>\n<p><em>\u00bfC\u00f3mo utilizas actualmente la API Kinsta? \u00bfQu\u00e9 funciones o mejoras te gustar\u00eda ver en futuras actualizaciones?<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Los plugins desempe\u00f1an un papel vital en la personalizaci\u00f3n y mejora de tus sitios de WordPress. Se utilizan para a\u00f1adir funcionalidades como formularios de contacto, comercio &#8230;<\/p>\n","protected":false},"author":287,"featured_media":73656,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_kinsta_gated_content":false,"_kinsta_gated_content_redirect":"","footnotes":""},"tags":[],"topic":[1270,1352,1321,1302],"class_list":["post-73655","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","topic-api","topic-plugins-wordpress","topic-react","topic-servicios-kinsta"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v24.6 (Yoast SEO v24.6) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Actualizar plugins de WordPress en m\u00faltiples sitios con la API de Kinsta - Kinsta\u00ae<\/title>\n<meta name=\"description\" content=\"Agiliza tu gesti\u00f3n de WordPress con nuestra gu\u00eda para crear una herramienta de actualizaci\u00f3n masiva de plugins en varios sitios mediante la API de Kinsta.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/kinsta.com\/es\/blog\/actualizacion-masiva-de-plugins-wordpress\/\" \/>\n<meta property=\"og:locale\" content=\"es_ES\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Construye una herramienta para actualizar masivamente plugins de WordPress en varios sitios con la API de Kinsta\" \/>\n<meta property=\"og:description\" content=\"Agiliza tu gesti\u00f3n de WordPress con nuestra gu\u00eda para crear una herramienta de actualizaci\u00f3n masiva de plugins en varios sitios mediante la API de Kinsta.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/kinsta.com\/es\/blog\/actualizacion-masiva-de-plugins-wordpress\/\" \/>\n<meta property=\"og:site_name\" content=\"Kinsta\u00ae\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/kinsta.es\/\" \/>\n<meta property=\"article:published_time\" content=\"2024-02-14T18:16:46+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-02-26T07:09:35+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2024\/02\/wp-bulk-update-plugins-wordpress.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1460\" \/>\n\t<meta property=\"og:image:height\" content=\"730\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Joel Olawanle\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:description\" content=\"Agiliza tu gesti\u00f3n de WordPress con nuestra gu\u00eda para crear una herramienta de actualizaci\u00f3n masiva de plugins en varios sitios mediante la API de Kinsta.\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2024\/02\/wp-bulk-update-plugins-wordpress.jpg\" \/>\n<meta name=\"twitter:creator\" content=\"@olawanle_joel\" \/>\n<meta name=\"twitter:site\" content=\"@Kinsta_ES\" \/>\n<meta name=\"twitter:label1\" content=\"Escrito por\" \/>\n\t<meta name=\"twitter:data1\" content=\"Joel Olawanle\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tiempo de lectura\" \/>\n\t<meta name=\"twitter:data2\" content=\"20 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/kinsta.com\/es\/blog\/actualizacion-masiva-de-plugins-wordpress\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/kinsta.com\/es\/blog\/actualizacion-masiva-de-plugins-wordpress\/\"},\"author\":{\"name\":\"Joel Olawanle\",\"@id\":\"https:\/\/kinsta.com\/es\/#\/schema\/person\/efa7de30245ca15be5ce1dcacff89c07\"},\"headline\":\"Construye una herramienta para actualizar masivamente plugins de WordPress en varios sitios con la API de Kinsta\",\"datePublished\":\"2024-02-14T18:16:46+00:00\",\"dateModified\":\"2024-02-26T07:09:35+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/kinsta.com\/es\/blog\/actualizacion-masiva-de-plugins-wordpress\/\"},\"wordCount\":3395,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/kinsta.com\/es\/#organization\"},\"image\":{\"@id\":\"https:\/\/kinsta.com\/es\/blog\/actualizacion-masiva-de-plugins-wordpress\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2024\/02\/wp-bulk-update-plugins-wordpress.jpg\",\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/kinsta.com\/es\/blog\/actualizacion-masiva-de-plugins-wordpress\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/kinsta.com\/es\/blog\/actualizacion-masiva-de-plugins-wordpress\/\",\"url\":\"https:\/\/kinsta.com\/es\/blog\/actualizacion-masiva-de-plugins-wordpress\/\",\"name\":\"Actualizar plugins de WordPress en m\u00faltiples sitios con la API de Kinsta - Kinsta\u00ae\",\"isPartOf\":{\"@id\":\"https:\/\/kinsta.com\/es\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/kinsta.com\/es\/blog\/actualizacion-masiva-de-plugins-wordpress\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/kinsta.com\/es\/blog\/actualizacion-masiva-de-plugins-wordpress\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2024\/02\/wp-bulk-update-plugins-wordpress.jpg\",\"datePublished\":\"2024-02-14T18:16:46+00:00\",\"dateModified\":\"2024-02-26T07:09:35+00:00\",\"description\":\"Agiliza tu gesti\u00f3n de WordPress con nuestra gu\u00eda para crear una herramienta de actualizaci\u00f3n masiva de plugins en varios sitios mediante la API de Kinsta.\",\"breadcrumb\":{\"@id\":\"https:\/\/kinsta.com\/es\/blog\/actualizacion-masiva-de-plugins-wordpress\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/kinsta.com\/es\/blog\/actualizacion-masiva-de-plugins-wordpress\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/kinsta.com\/es\/blog\/actualizacion-masiva-de-plugins-wordpress\/#primaryimage\",\"url\":\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2024\/02\/wp-bulk-update-plugins-wordpress.jpg\",\"contentUrl\":\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2024\/02\/wp-bulk-update-plugins-wordpress.jpg\",\"width\":1460,\"height\":730},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/kinsta.com\/es\/blog\/actualizacion-masiva-de-plugins-wordpress\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/kinsta.com\/es\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Servicios Kinsta\",\"item\":\"https:\/\/kinsta.com\/es\/secciones\/servicios-kinsta\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Construye una herramienta para actualizar masivamente plugins de WordPress en varios sitios con la API de Kinsta\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/kinsta.com\/es\/#website\",\"url\":\"https:\/\/kinsta.com\/es\/\",\"name\":\"Kinsta\u00ae\",\"description\":\"Soluciones de alojamiento premium, r\u00e1pidas y seguras\",\"publisher\":{\"@id\":\"https:\/\/kinsta.com\/es\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/kinsta.com\/es\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/kinsta.com\/es\/#organization\",\"name\":\"Kinsta\",\"url\":\"https:\/\/kinsta.com\/es\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/kinsta.com\/es\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2023\/12\/kinsta-logo.jpeg\",\"contentUrl\":\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2023\/12\/kinsta-logo.jpeg\",\"width\":500,\"height\":500,\"caption\":\"Kinsta\"},\"image\":{\"@id\":\"https:\/\/kinsta.com\/es\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/kinsta.es\/\",\"https:\/\/x.com\/Kinsta_ES\",\"https:\/\/www.instagram.com\/kinstahosting\/\",\"https:\/\/www.linkedin.com\/company\/kinsta\/\",\"https:\/\/www.pinterest.com\/kinstahosting\/\",\"https:\/\/www.youtube.com\/c\/Kinsta\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/kinsta.com\/es\/#\/schema\/person\/efa7de30245ca15be5ce1dcacff89c07\",\"name\":\"Joel Olawanle\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/kinsta.com\/es\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/051bf577ce2c837846a1db9eef184758?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/051bf577ce2c837846a1db9eef184758?s=96&d=mm&r=g\",\"caption\":\"Joel Olawanle\"},\"description\":\"Joel is a Frontend developer working at Kinsta as a Technical Editor. He is a passionate teacher with love for open source and has written over 300 technical articles majorly around JavaScript and it's frameworks.\",\"sameAs\":[\"https:\/\/joelolawanle.com\/\",\"https:\/\/www.linkedin.com\/in\/olawanlejoel\/\",\"https:\/\/x.com\/olawanle_joel\",\"https:\/\/www.youtube.com\/@joelolawanle\"],\"gender\":\"male\",\"knowsAbout\":[\"JavaScript\",\"React\",\"Next.js\"],\"knowsLanguage\":[\"English\"],\"jobTitle\":\"Technical Editor\",\"worksFor\":\"Kinsta\",\"url\":\"https:\/\/kinsta.com\/es\/blog\/author\/joelolawanle\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Actualizar plugins de WordPress en m\u00faltiples sitios con la API de Kinsta - Kinsta\u00ae","description":"Agiliza tu gesti\u00f3n de WordPress con nuestra gu\u00eda para crear una herramienta de actualizaci\u00f3n masiva de plugins en varios sitios mediante la API de Kinsta.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/kinsta.com\/es\/blog\/actualizacion-masiva-de-plugins-wordpress\/","og_locale":"es_ES","og_type":"article","og_title":"Construye una herramienta para actualizar masivamente plugins de WordPress en varios sitios con la API de Kinsta","og_description":"Agiliza tu gesti\u00f3n de WordPress con nuestra gu\u00eda para crear una herramienta de actualizaci\u00f3n masiva de plugins en varios sitios mediante la API de Kinsta.","og_url":"https:\/\/kinsta.com\/es\/blog\/actualizacion-masiva-de-plugins-wordpress\/","og_site_name":"Kinsta\u00ae","article_publisher":"https:\/\/www.facebook.com\/kinsta.es\/","article_published_time":"2024-02-14T18:16:46+00:00","article_modified_time":"2024-02-26T07:09:35+00:00","og_image":[{"width":1460,"height":730,"url":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2024\/02\/wp-bulk-update-plugins-wordpress.jpg","type":"image\/jpeg"}],"author":"Joel Olawanle","twitter_card":"summary_large_image","twitter_description":"Agiliza tu gesti\u00f3n de WordPress con nuestra gu\u00eda para crear una herramienta de actualizaci\u00f3n masiva de plugins en varios sitios mediante la API de Kinsta.","twitter_image":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2024\/02\/wp-bulk-update-plugins-wordpress.jpg","twitter_creator":"@olawanle_joel","twitter_site":"@Kinsta_ES","twitter_misc":{"Escrito por":"Joel Olawanle","Tiempo de lectura":"20 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/kinsta.com\/es\/blog\/actualizacion-masiva-de-plugins-wordpress\/#article","isPartOf":{"@id":"https:\/\/kinsta.com\/es\/blog\/actualizacion-masiva-de-plugins-wordpress\/"},"author":{"name":"Joel Olawanle","@id":"https:\/\/kinsta.com\/es\/#\/schema\/person\/efa7de30245ca15be5ce1dcacff89c07"},"headline":"Construye una herramienta para actualizar masivamente plugins de WordPress en varios sitios con la API de Kinsta","datePublished":"2024-02-14T18:16:46+00:00","dateModified":"2024-02-26T07:09:35+00:00","mainEntityOfPage":{"@id":"https:\/\/kinsta.com\/es\/blog\/actualizacion-masiva-de-plugins-wordpress\/"},"wordCount":3395,"commentCount":0,"publisher":{"@id":"https:\/\/kinsta.com\/es\/#organization"},"image":{"@id":"https:\/\/kinsta.com\/es\/blog\/actualizacion-masiva-de-plugins-wordpress\/#primaryimage"},"thumbnailUrl":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2024\/02\/wp-bulk-update-plugins-wordpress.jpg","inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/kinsta.com\/es\/blog\/actualizacion-masiva-de-plugins-wordpress\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/kinsta.com\/es\/blog\/actualizacion-masiva-de-plugins-wordpress\/","url":"https:\/\/kinsta.com\/es\/blog\/actualizacion-masiva-de-plugins-wordpress\/","name":"Actualizar plugins de WordPress en m\u00faltiples sitios con la API de Kinsta - Kinsta\u00ae","isPartOf":{"@id":"https:\/\/kinsta.com\/es\/#website"},"primaryImageOfPage":{"@id":"https:\/\/kinsta.com\/es\/blog\/actualizacion-masiva-de-plugins-wordpress\/#primaryimage"},"image":{"@id":"https:\/\/kinsta.com\/es\/blog\/actualizacion-masiva-de-plugins-wordpress\/#primaryimage"},"thumbnailUrl":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2024\/02\/wp-bulk-update-plugins-wordpress.jpg","datePublished":"2024-02-14T18:16:46+00:00","dateModified":"2024-02-26T07:09:35+00:00","description":"Agiliza tu gesti\u00f3n de WordPress con nuestra gu\u00eda para crear una herramienta de actualizaci\u00f3n masiva de plugins en varios sitios mediante la API de Kinsta.","breadcrumb":{"@id":"https:\/\/kinsta.com\/es\/blog\/actualizacion-masiva-de-plugins-wordpress\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/kinsta.com\/es\/blog\/actualizacion-masiva-de-plugins-wordpress\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/kinsta.com\/es\/blog\/actualizacion-masiva-de-plugins-wordpress\/#primaryimage","url":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2024\/02\/wp-bulk-update-plugins-wordpress.jpg","contentUrl":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2024\/02\/wp-bulk-update-plugins-wordpress.jpg","width":1460,"height":730},{"@type":"BreadcrumbList","@id":"https:\/\/kinsta.com\/es\/blog\/actualizacion-masiva-de-plugins-wordpress\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/kinsta.com\/es\/"},{"@type":"ListItem","position":2,"name":"Servicios Kinsta","item":"https:\/\/kinsta.com\/es\/secciones\/servicios-kinsta\/"},{"@type":"ListItem","position":3,"name":"Construye una herramienta para actualizar masivamente plugins de WordPress en varios sitios con la API de Kinsta"}]},{"@type":"WebSite","@id":"https:\/\/kinsta.com\/es\/#website","url":"https:\/\/kinsta.com\/es\/","name":"Kinsta\u00ae","description":"Soluciones de alojamiento premium, r\u00e1pidas y seguras","publisher":{"@id":"https:\/\/kinsta.com\/es\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/kinsta.com\/es\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":"Organization","@id":"https:\/\/kinsta.com\/es\/#organization","name":"Kinsta","url":"https:\/\/kinsta.com\/es\/","logo":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/kinsta.com\/es\/#\/schema\/logo\/image\/","url":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2023\/12\/kinsta-logo.jpeg","contentUrl":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2023\/12\/kinsta-logo.jpeg","width":500,"height":500,"caption":"Kinsta"},"image":{"@id":"https:\/\/kinsta.com\/es\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/kinsta.es\/","https:\/\/x.com\/Kinsta_ES","https:\/\/www.instagram.com\/kinstahosting\/","https:\/\/www.linkedin.com\/company\/kinsta\/","https:\/\/www.pinterest.com\/kinstahosting\/","https:\/\/www.youtube.com\/c\/Kinsta"]},{"@type":"Person","@id":"https:\/\/kinsta.com\/es\/#\/schema\/person\/efa7de30245ca15be5ce1dcacff89c07","name":"Joel Olawanle","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/kinsta.com\/es\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/051bf577ce2c837846a1db9eef184758?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/051bf577ce2c837846a1db9eef184758?s=96&d=mm&r=g","caption":"Joel Olawanle"},"description":"Joel is a Frontend developer working at Kinsta as a Technical Editor. He is a passionate teacher with love for open source and has written over 300 technical articles majorly around JavaScript and it's frameworks.","sameAs":["https:\/\/joelolawanle.com\/","https:\/\/www.linkedin.com\/in\/olawanlejoel\/","https:\/\/x.com\/olawanle_joel","https:\/\/www.youtube.com\/@joelolawanle"],"gender":"male","knowsAbout":["JavaScript","React","Next.js"],"knowsLanguage":["English"],"jobTitle":"Technical Editor","worksFor":"Kinsta","url":"https:\/\/kinsta.com\/es\/blog\/author\/joelolawanle\/"}]}},"acf":[],"_links":{"self":[{"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/posts\/73655","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/users\/287"}],"replies":[{"embeddable":true,"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/comments?post=73655"}],"version-history":[{"count":5,"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/posts\/73655\/revisions"}],"predecessor-version":[{"id":73875,"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/posts\/73655\/revisions\/73875"}],"alternate":[{"embeddable":true,"hreflang":"en","title":"English","href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/73655\/translations\/en"},{"embeddable":true,"hreflang":"it","title":"Italian","href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/73655\/translations\/it"},{"embeddable":true,"hreflang":"pt","title":"Portuguese","href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/73655\/translations\/pt"},{"embeddable":true,"hreflang":"fr","title":"French","href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/73655\/translations\/fr"},{"embeddable":true,"hreflang":"de","title":"German","href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/73655\/translations\/de"},{"embeddable":true,"hreflang":"ja","title":"Japanese","href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/73655\/translations\/jp"},{"embeddable":true,"hreflang":"es","title":"Spanish","href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/73655\/translations\/es"},{"embeddable":true,"hreflang":"nl","title":"Dutch","href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/73655\/translations\/nl"},{"href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/73655\/tree"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/media\/73656"}],"wp:attachment":[{"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/media?parent=73655"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/tags?post=73655"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/topic?post=73655"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}