[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of admin-pages/messages/es.json from the admin-pages VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin/pages.admin-menu-button.content-pages": "Páginas de contenido",
  "admin/pages.admin-menu-button.pages": "Páginas",
  "admin/pages.admin-menu-button.site-editor-smb": "Site Editor",
  "admin/pages.admin-menu-button.site-editor": "Site Editor",
  "admin/pages.admin-menu-button.store": "Tienda",
  "admin/pages.admin-menu-button.styles": "Estilos",
  "admin/pages.admin.content.content.section-title": "Contenido",
  "admin/pages.admin.content.general.description.label": "Descripción",
  "admin/pages.admin.content.general.section-title": "General",
  "admin/pages.admin.content.general.seo.description": "<La descripción es el texto comúnmente utilizado por Google para mostrar los resultados de texto de la segunda y tercera línea de los resultados de búsqueda, justo debajo del título>",
  "admin/pages.admin.content.general.seo.page-title": "<Título de la página>",
  "admin/pages.admin.content.general.title.label": "Título",
  "admin/pages.admin.content.general.title.placeholder": "ex.: Quienes somos",
  "admin/pages.admin.content.general.url.label": "URL",
  "admin/pages.admin.content.general.url.placeholder": "ej.: /quienes-somos",
  "admin/pages.admin.content.not-supported.action": "Ver instrucciones",
  "admin/pages.admin.content.not-supported.description": "El tema instalado en tu tienda no admite la creación de páginas de contenido personalizado. Si necesitas crear páginas, elige otro tema que admita esta funcionalidad o, si utilizas un tema personalizado, pide al desarrollador que siga las instrucciones que se indican en link a continuación.",
  "admin/pages.admin.content.not-supported.title": "Esta funcionalidad no está disponible",
  "admin/pages.admin.loading": "Cargando",
  "admin/pages.admin.pages.form.button.cancel": "Cancelar",
  "admin/pages.admin.pages.form.button.delete": "Eliminar",
  "admin/pages.admin.pages.form.button.save": "Guardar",
  "admin/pages.admin.pages.form.delete.error": "Error al eliminar la ruta.",
  "admin/pages.admin.pages.form.delete.success": "Éxito",
  "admin/pages.admin.pages.form.details.path-hint": "/nueva-pagina",
  "admin/pages.admin.pages.form.details.title": "Detalles de la página",
  "admin/pages.admin.pages.form.field.array.item.apply": "Aplicar",
  "admin/pages.admin.pages.form.field.array.item.delete": "Eliminar",
  "admin/pages.admin.pages.form.field.array.item.edit": "Editar",
  "admin/pages.admin.pages.form.field.array.item": "Ítem",
  "admin/pages.admin.pages.form.field.login": "Requiere autenticación",
  "admin/pages.admin.pages.form.field.meta.description.no-options": "Escribe tu palabra clave y presiona ENTER para agregarla.",
  "admin/pages.admin.pages.form.field.meta.description": "Descripción",
  "admin/pages.admin.pages.form.field.meta.robots": "Robots",
  "admin/pages.admin.pages.form.field.meta.keywords.create": "Crear palabra clave \"{keyword}\"",
  "admin/pages.admin.pages.form.field.meta.keywords": "Palabras clave",
  "admin/pages.admin.pages.form.field.path": "URL",
  "admin/pages.admin.pages.form.field.title": "Título",
  "admin/pages.admin.pages.form.save.error": "Error al guardar la redirección.",
  "admin/pages.admin.pages.form.save.success": "Éxito",
  "admin/pages.admin.pages.form.templates.conditional.addButton": "Agregar template condicional",
  "admin/pages.admin.pages.form.templates.conditional.description": "Un template condicional te permite utilizar diseño diferente en tu página. Este diseño aparecerá cuando corresponda a las condiciones definidas.",
  "admin/pages.admin.pages.form.templates.conditional.template.label": "Template",
  "admin/pages.admin.pages.form.templates.conditional.title": "Condicional",
  "admin/pages.admin.pages.form.templates.field.default": "Predeterminado",
  "admin/pages.admin.pages.form.templates.field.required": "Obligatorio",
  "admin/pages.admin.pages.form.templates.path.invalid-format": "URL inválida.",
  "admin/pages.admin.pages.form.templates.path.validation-error": "La URL debe comenzar con '/'.",
  "admin/pages.admin.pages.form.templates.simple.conditions.add-button": "Agregar nueva condición",
  "admin/pages.admin.pages.form.templates.simple.conditions.category-placeholder": "Selecciona el tipo de condición",
  "admin/pages.admin.pages.form.templates.simple.conditions.date.equals": "es",
  "admin/pages.admin.pages.form.templates.simple.conditions.date.from": "comienza el",
  "admin/pages.admin.pages.form.templates.simple.conditions.date.range.and": "y",
  "admin/pages.admin.pages.form.templates.simple.conditions.date.range": "está entre",
  "admin/pages.admin.pages.form.templates.simple.conditions.date.to": "termina el",
  "admin/pages.admin.pages.form.templates.simple.conditions.date": "Fecha",
  "admin/pages.admin.pages.form.templates.simple.conditions.header-prefix": "Correspondiente a",
  "admin/pages.admin.pages.form.templates.simple.conditions.header-suffix": "las siguientes condiciones",
  "admin/pages.admin.pages.form.templates.simple.conditions.no-conditions": "Ninguna condición seleccionada",
  "admin/pages.admin.pages.form.templates.simple.conditions.operator-all": "todas las",
  "admin/pages.admin.pages.form.templates.simple.conditions.operator-and": "y",
  "admin/pages.admin.pages.form.templates.simple.conditions.operator-any": "cualquiera de las",
  "admin/pages.admin.pages.form.templates.simple.conditions.operator-or": "o",
  "admin/pages.admin.pages.form.templates.title": "Templates",
  "admin/pages.admin.pages.form.title.new": "Nueva página",
  "admin/pages.admin.pages.list.button.create": "Crear nueva",
  "admin/pages.admin.pages.list.section.notFound": "No encontrado (404)",
  "admin/pages.admin.pages.list.section.product": "Producto",
  "admin/pages.admin.pages.list.section.productCollections": "Colecciones de productos",
  "admin/pages.admin.pages.list.section.standard": "Predeterminado",
  "admin/pages.admin.redirects.bulk.failed.button": "Ver errores",
  "admin/pages.admin.redirects.bulk.failed": "No pudimos procesar todas las líneas ({lines}) del archivo {fileName}. Por favor, inténtalo de nuevo.",
  "admin/pages.admin.redirects.bulk.partial": "La importación del archivo {fileName} ha sido parcialmente exitosa: {success} líneas procesadas con éxito, {failed} líneas no procesadas.",
  "admin/pages.admin.redirects.bulk.success": "Operación completada. Se procesaron con éxito {lines} líneas del archivo \"{fileName}\".",
  "admin/pages.admin.redirects.button.create": "Nueva redirección",
  "admin/pages.admin.redirects.emptyState.upload": "Importa un CSV",
  "admin/pages.admin.redirects.emptyState": "Ninguna redirección creada.",
  "admin/pages.admin.redirects.error.retry": "Inténtalo de nuevo",
  "admin/pages.admin.redirects.error": "Se produjo un error.",
  "admin/pages.admin.redirects.form.button.back": "Atrás",
  "admin/pages.admin.redirects.form.button.cancel": "Cancelar",
  "admin/pages.admin.redirects.form.button.remove": "Remover",
  "admin/pages.admin.redirects.form.button.replace": "Reemplazar",
  "admin/pages.admin.redirects.form.button.save": "Guardar",
  "admin/pages.admin.redirects.form.datePicker.title": "Fecha de fin",
  "admin/pages.admin.redirects.form.delete.error": "Error al eliminar la redirección.",
  "admin/pages.admin.redirects.form.modal.text": "¿Estás seguro de que deseas remover esta redirección?",
  "admin/pages.admin.redirects.form.save.error": "Error al guardar la redirección.",
  "admin/pages.admin.redirects.form.title.info": "Información de la redirección",
  "admin/pages.admin.redirects.form.title.new": "Crear una redirección",
  "admin/pages.admin.redirects.form.toggle.endDate": "Esta redirección tiene una fecha de fin",
  "admin/pages.admin.redirects.form.toggle.permanent": "Esta redirección es permanente (Código: 301).",
  "admin/pages.admin.redirects.form.toggle.temporary": "Esta redirección es temporal (Código: 302).",
  "admin/pages.admin.redirects.import-error.button.cancel": "Cancelar",
  "admin/pages.admin.redirects.import-error.button.download": "Descargar",
  "admin/pages.admin.redirects.import-error.button.retry": "Reintentar",
  "admin/pages.admin.redirects.import-error.retry-fail": "El reintento falló: {success} exitosas, {failed} fallidas.",
  "admin/pages.admin.redirects.import-error.retry-success": "Reintento exitoso.",
  "admin/pages.admin.redirects.import-error.title": "Redirecciones fallidas",
  "admin/pages.admin.redirects.or.text": "o",
  "admin/pages.admin.redirects.pagination.showRows": "Número de filas",
  "admin/pages.admin.redirects.table.endDate.default": "no establecida",
  "admin/pages.admin.redirects.table.endDate.title": "Fecha de fin",
  "admin/pages.admin.redirects.table.from": "De",
  "admin/pages.admin.redirects.table.to": "Para",
  "admin/pages.admin.redirects.table.toolbar.export": "Exportar",
  "admin/pages.admin.redirects.table.toolbar.fields.hide-all": "Ocultar todo",
  "admin/pages.admin.redirects.table.toolbar.fields.label": "Alternar campos visibles",
  "admin/pages.admin.redirects.table.toolbar.fields.show-all": "Mostrar todo",
  "admin/pages.admin.redirects.table.toolbar.import": "Importar",
  "admin/pages.admin.redirects.table.toolbar.line-density.high": "Alta",
  "admin/pages.admin.redirects.table.toolbar.line-density.label": "Densidad de línea",
  "admin/pages.admin.redirects.table.toolbar.line-density.low": "Baja",
  "admin/pages.admin.redirects.table.toolbar.line-density.medium": "Media",
  "admin/pages.admin.redirects.table.type.permanent": "Permanente (301)",
  "admin/pages.admin.redirects.table.type.temporary": "Temporal (302)",
  "admin/pages.admin.redirects.table.type": "Tipo",
  "admin/pages.admin.redirects.title": "Lista de redirecciones",
  "admin/pages.admin.redirects.upload-modal.error.line.title": "Errores en la línea ",
  "admin/pages.admin.redirects.upload-modal.fail.message": "Por favor, inténtalo de nuevo.",
  "admin/pages.admin.redirects.upload-modal.fail.subtitle": "Tus redirecciones no se pudieron cargar.",
  "admin/pages.admin.redirects.upload-modal.fail.title": "Se produjo un error.",
  "admin/pages.admin.redirects.upload-modal.loading.cancel": "Cancelar",
  "admin/pages.admin.redirects.upload-modal.loading.warning": "Por favor, no cierres esta ventana.",
  "admin/pages.admin.redirects.upload-modal.prompt.alert.unsupported-file": "Formato de archivo no admitido. Carga un archivo \".csv\".",
  "admin/pages.admin.redirects.upload-modal.prompt.alert.validation-errors.action": "Ver errores",
  "admin/pages.admin.redirects.upload-modal.prompt.alert.validation-errors": "Errores de validación en el archivo {name}",
  "admin/pages.admin.redirects.upload-modal.prompt.body.download-template": "Descargar plantilla",
  "admin/pages.admin.redirects.upload-modal.prompt.body": "Por favor, utiliza nuestra plantilla o un archivo exportado como base.",
  "admin/pages.admin.redirects.upload-modal.prompt.button.cancel": "Cancelar",
  "admin/pages.admin.redirects.upload-modal.prompt.button.import": "Importar archivo",
  "admin/pages.admin.redirects.upload-modal.prompt.drop.button": "selecciona un archivo",
  "admin/pages.admin.redirects.upload-modal.prompt.drop.message": "Suelta aquí tu CSV o ",
  "admin/pages.admin.redirects.upload-modal.prompt.select-action.body": "¿Deseas guardar o eliminar redirecciones?",
  "admin/pages.admin.redirects.upload-modal.prompt.select-action.delete": "Eliminar",
  "admin/pages.admin.redirects.upload-modal.prompt.select-action.save": "Guardar",
  "admin/pages.admin.redirects.upload-modal.prompt.select-action.title": "Importar CSV",
  "admin/pages.admin.redirects.upload-modal.prompt.validation-error.type": "[Línea {line}] \"{type}\" es un valor inválido para el tipo de redireccionamiento. Los valores permitidos son: \"PERMANENT\" y \"TEMPORARY\".",
  "admin/pages.admin.rich-text-editor.add-button": "Agregar",
  "admin/pages.admin.rich-text-editor.add-image.label": "URL de la imagen",
  "admin/pages.admin.rich-text-editor.add-image.placeholder": "Link",
  "admin/pages.admin.rich-text-editor.add-image.text-label": "Texto",
  "admin/pages.admin.rich-text-editor.add-image.title": "Insertar imagen",
  "admin/pages.admin.rich-text-editor.bold.title": "Negrita",
  "admin/pages.admin.rich-text-editor.heading.header-four": "Título 4",
  "admin/pages.admin.rich-text-editor.heading.header-one": "Título 1",
  "admin/pages.admin.rich-text-editor.heading.header-three": "Título 3",
  "admin/pages.admin.rich-text-editor.heading.header-two": "Título 2",
  "admin/pages.admin.rich-text-editor.heading.title": "Estilos",
  "admin/pages.admin.rich-text-editor.heading.unstyled": "Texto normal",
  "admin/pages.admin.rich-text-editor.italic.title": "Cursiva",
  "admin/pages.admin.rich-text-editor.link.title": "Insertar link",
  "admin/pages.admin.rich-text-editor.ordered-list.title": "Lista ordenada",
  "admin/pages.admin.rich-text-editor.underline.title": "Subrayado",
  "admin/pages.admin.rich-text-editor.unordered-list.title": "Lista sin ordenar",
  "admin/pages.admin.rich-text-editor.upload-button": "Cargar",
  "admin/pages.admin.rich-text-editor.upload-image-label": "Selecciona una imagen para cargar",
  "admin/pages.admin.tabs.pages": "Páginas",
  "admin/pages.admin.tabs.redirects": "Redirecciones",
  "admin/pages.editor.component-list.action-menu.delete": "Eliminar",
  "admin/pages.editor.component-list.action-menu.activate": "Activar",
  "admin/pages.editor.component-list.action-menu.reset": "Restablecer",
  "admin/pages.editor.component-list.action-menu.tooltip": "Esta tarjeta está siendo editada.",
  "admin/pages.editor.component-list.back": "Atrás",
  "admin/pages.editor.component-list.status.active": "Activo",
  "admin/pages.editor.component-list.status.inactive": "Inactivo",
  "admin/pages.editor.component-list.status.scheduled": "Programado",
  "admin/pages.editor.component-list.title": "Versiones",
  "admin/pages.editor.component-list.untitled": "Bloque sin título",
  "admin/pages.editor.components.status.alert": "Esta versión del contenido no se muestra en la vista previa ni a los visitantes.",
  "admin/pages.editor.components.editable.alert": "La edición de esta página se reflejará en cada página de subcategoría. Si deseas que se herede el contenido del nivel principal (categoría), restablece su contenido.",
  "admin/pages.editor.components.arrayTemplate.button.add": "Agregar",
  "admin/pages.editor.components.button.cancel": "Cancelar",
  "admin/pages.editor.components.button.save": "Guardar",
  "admin/pages.editor.components.condition.date.title": "Fecha personalizada",
  "admin/pages.editor.components.condition.date.toggle.start": "Programar una fecha de inicio",
  "admin/pages.editor.components.condition.date.toggle.end": "Programar una fecha de fin",
  "admin/pages.editor.components.condition.visibility.activation.disabled": "No puedes desactivar el contenido. Elige la versión que quieras activar y esta se desactivará automáticamente.",
  "admin/pages.editor.components.condition.visibility.activation.warning": "El contenido que está actualmente activo se desactivará.",
  "admin/pages.editor.components.condition.scope.entity.brand": "esta marca",
  "admin/pages.editor.components.condition.scope.entity.category": "esta categoría",
  "admin/pages.editor.components.condition.scope.entity.custom": "esta URL",
  "admin/pages.editor.components.condition.scope.entity.department": "este departamento",
  "admin/pages.editor.components.condition.scope.entity.product": "este producto",
  "admin/pages.editor.components.condition.scope.entity.route": "esta URL",
  "admin/pages.editor.components.condition.scope.entity.search": "esta búsqueda",
  "admin/pages.editor.components.condition.scope.entity.subcategory": "esta subcategoría",
  "admin/pages.editor.components.condition.scope.sitewide": "todo el sitio",
  "admin/pages.editor.components.condition.scope.template": "este template",
  "admin/pages.editor.components.condition.scope.title": "Aplicar a",
  "admin/pages.editor.components.condition.title": "Visibilidad",
  "admin/pages.editor.components.condition.visibility.activation": "Activar ahora",
  "admin/pages.editor.components.condition.toast.error.page-context": "No se pudo identificar {entity}. La configuración se definirá como \"{template}\".",
  "admin/pages.editor.components.modal.back.button.discard": "Descartar",
  "admin/pages.editor.components.modal.back.button.save": "Guardar",
  "admin/pages.editor.components.modal.back.text": "Se perderán tus cambios sin guardar. ¿Deseas guardarlos?",
  "admin/pages.editor.components.modal.form.button.cancel": "Cancelar",
  "admin/pages.editor.components.modal.form.text": "Tienes cambios sin guardar. ¿Estás seguro de que deseas continuar y descartar tus cambios? Esta acción no se puede deshacer.",
  "admin/pages.editor.components.modal.form.title": "Cambios sin guardar",
  "admin/pages.editor.components.modal.list.delete.active.text": "Estás intentando eliminar el contenido activo. El próximo contenido disponible lo reemplazará. ¿Estás seguro de que deseas continuar? Esta acción no se puede deshacer.",
  "admin/pages.editor.components.modal.list.delete.active.title": "Eliminar contenido activo",
  "admin/pages.editor.components.modal.list.delete.button.cancel": "Cancelar",
  "admin/pages.editor.components.modal.list.delete.button.delete": "Eliminar",
  "admin/pages.editor.components.modal.list.delete.inactive.text": "¿Estás seguro de que deseas eliminar este contenido? Esta acción no se puede deshacer.",
  "admin/pages.editor.components.modal.list.delete.inactive.title": "Eliminar contenido",
  "admin/pages.editor.components.modal.list.reset.button.reset": "Restablecer",
  "admin/pages.editor.components.modal.list.reset.text": "Estás intentando restablecer el contenido creado por una aplicación. Esta acción descartará cualquier cambio que hayas realizado. ¿Estás seguro de que deseas continuar? Esta acción no se puede deshacer.",
  "admin/pages.editor.components.modal.list.reset.title": "Restablecer el contenido de la aplicación",
  "admin/pages.editor.components.no-image": "Sin imagen",
  "admin/pages.editor.components.open.error": "Se produjo un error. Por favor, inténtalo de nuevo.",
  "admin/pages.editor.components.title": "Bloques",
  "admin/pages.editor.components.toast.delete.error": "Se produjo un error. Por favor, inténtalo de nuevo.",
  "admin/pages.editor.components.toast.delete.success": "Contenido eliminado con éxito.",
  "admin/pages.editor.components.toast.reset.error": "Se produjo un error. Por favor, inténtalo de nuevo.",
  "admin/pages.editor.components.toast.reset.success": "Contenido restablecido con éxito.",
  "admin/pages.editor.components.toast.save.error": "Se produjo un error. Por favor, inténtalo de nuevo.",
  "admin/pages.editor.components.toast.save.success": "Contenido guardado con éxito.",
  "admin/pages.editor.configuration.button.create": "Nueva versión",
  "admin/pages.editor.configuration.condition.date.from": "Inicio:",
  "admin/pages.editor.configuration.condition.date.to": "Fin:",
  "admin/pages.editor.configuration.createdBy": "Creado por {name}",
  "admin/pages.editor.configuration.defaultTitle": "Contenido sin título",
  "admin/pages.editor.configuration.scope.sitewide.context": "todo el sitio",
  "admin/pages.editor.configuration.scope.sitewide.saved": "Guardado el",
  "admin/pages.editor.configuration.scope.template.context": "template",
  "admin/pages.editor.configuration.scope.template.saved": "Guardado en el",
  "admin/pages.editor.configuration.tag.editing": "Editando",
  "admin/pages.editor.container.dev-mode-warning.text": "Estás en el modo de desarrollo. Los cambios en el contenido no se reflejarán en la tienda de producción.",
  "admin/pages.editor.container.editpath.label": "URL",
  "admin/pages.editor.container.master-workspace-warning.text": "Estás editando la tienda en producción. Los cambios en el contenido tendrán un efecto inmediato.",
  "admin/pages.editor.iframe.confirm-prompt": "¿Estás seguro de que deseas salir?",
  "admin/pages.editor.image-uploader.empty.button": "Arrastra y suelta una imagen o haz clic para seleccionarla",
  "admin/pages.editor.image-uploader.empty.subtext-1": "o",
  "admin/pages.editor.image-uploader.empty.subtext-2": "arrastra y suelta",
  "admin/pages.editor.image-uploader.empty.subtext-3": "una imagen",
  "admin/pages.editor.image-uploader.error.file-size": "El archivo supera el límite de tamaño de 4 MB. Por favor, selecciona un archivo más pequeño.",
  "admin/pages.editor.image-uploader.error.generic": "Se produjo un error. Por favor, inténtalo de nuevo.",
  "admin/pages.editor.locale.aa": "Afar",
  "admin/pages.editor.locale.ab": "Abjasio",
  "admin/pages.editor.locale.ae": "Avéstico",
  "admin/pages.editor.locale.af": "Afrikáans",
  "admin/pages.editor.locale.ak": "Akan",
  "admin/pages.editor.locale.am": "Amárico",
  "admin/pages.editor.locale.an": "Aragonés",
  "admin/pages.editor.locale.ar": "Árabe",
  "admin/pages.editor.locale.as": "Asamés",
  "admin/pages.editor.locale.av": "Avar",
  "admin/pages.editor.locale.ay": "Aimara",
  "admin/pages.editor.locale.az": "Azerí",
  "admin/pages.editor.locale.ba": "Baskir",
  "admin/pages.editor.locale.be": "Bielorruso",
  "admin/pages.editor.locale.bg": "Búlgaro",
  "admin/pages.editor.locale.bh": "Bihari",
  "admin/pages.editor.locale.bi": "Bislama",
  "admin/pages.editor.locale.bm": "Bambara",
  "admin/pages.editor.locale.bn": "Bengalí",
  "admin/pages.editor.locale.bo": "Tibetano",
  "admin/pages.editor.locale.br": "Bretón",
  "admin/pages.editor.locale.bs": "Bosnio",
  "admin/pages.editor.locale.ca": "Catalán",
  "admin/pages.editor.locale.ce": "Checheno",
  "admin/pages.editor.locale.ch": "Chamorro",
  "admin/pages.editor.locale.co": "Corso",
  "admin/pages.editor.locale.cr": "Cree",
  "admin/pages.editor.locale.cs": "Checo",
  "admin/pages.editor.locale.cu": "Eslavo eclesiástico",
  "admin/pages.editor.locale.cv": "Chuvasio",
  "admin/pages.editor.locale.cy": "Galés",
  "admin/pages.editor.locale.da": "Danés",
  "admin/pages.editor.locale.de": "Alemán",
  "admin/pages.editor.locale.dv": "Divehi",
  "admin/pages.editor.locale.dz": "Dzongkha",
  "admin/pages.editor.locale.ee": "Ewé",
  "admin/pages.editor.locale.el": "Griego",
  "admin/pages.editor.locale.en": "Inglés",
  "admin/pages.editor.locale.eo": "Esperanto",
  "admin/pages.editor.locale.es": "Español",
  "admin/pages.editor.locale.et": "Estonio",
  "admin/pages.editor.locale.eu": "Euskera",
  "admin/pages.editor.locale.fa": "Persa",
  "admin/pages.editor.locale.ff": "Fula",
  "admin/pages.editor.locale.fi": "Finés",
  "admin/pages.editor.locale.fj": "Fiyiano",
  "admin/pages.editor.locale.fo": "Feroés",
  "admin/pages.editor.locale.fr": "Francés",
  "admin/pages.editor.locale.fy": "Frisón occidental",
  "admin/pages.editor.locale.ga": "Irlandés",
  "admin/pages.editor.locale.gd": "Gaélico escocés",
  "admin/pages.editor.locale.gl": "Gallego",
  "admin/pages.editor.locale.gn": "Guaraní",
  "admin/pages.editor.locale.gu": "Guyaratí",
  "admin/pages.editor.locale.gv": "Manés",
  "admin/pages.editor.locale.ha": "Hausa",
  "admin/pages.editor.locale.he": "Hebreo",
  "admin/pages.editor.locale.hi": "Hindi",
  "admin/pages.editor.locale.ho": "Hiri motu",
  "admin/pages.editor.locale.hr": "Croata",
  "admin/pages.editor.locale.ht": "Criollo haitiano",
  "admin/pages.editor.locale.hu": "Húngaro",
  "admin/pages.editor.locale.hy": "Armenio",
  "admin/pages.editor.locale.hz": "Herero",
  "admin/pages.editor.locale.ia": "Interlingua",
  "admin/pages.editor.locale.id": "Indonesio",
  "admin/pages.editor.locale.ie": "Interlingue",
  "admin/pages.editor.locale.ig": "Igbo",
  "admin/pages.editor.locale.ii": "Yi de Sichuán",
  "admin/pages.editor.locale.ik": "Iñupiaq",
  "admin/pages.editor.locale.io": "Ido",
  "admin/pages.editor.locale.is": "Islandés",
  "admin/pages.editor.locale.it": "Italiano",
  "admin/pages.editor.locale.iu": "Inuktitut",
  "admin/pages.editor.locale.ja": "Japonés",
  "admin/pages.editor.locale.jv": "Javanés",
  "admin/pages.editor.locale.ka": "Georgiano",
  "admin/pages.editor.locale.kg": "Kongo",
  "admin/pages.editor.locale.ki": "Kikuyu",
  "admin/pages.editor.locale.kj": "Kuanyama",
  "admin/pages.editor.locale.kk": "Kazajo",
  "admin/pages.editor.locale.kl": "Groenlandés",
  "admin/pages.editor.locale.km": "Jemer",
  "admin/pages.editor.locale.kn": "Canarés",
  "admin/pages.editor.locale.ko": "Coreano",
  "admin/pages.editor.locale.kr": "Kanuri",
  "admin/pages.editor.locale.ks": "Cachemiro",
  "admin/pages.editor.locale.ku": "Kurdo",
  "admin/pages.editor.locale.kv": "Komi",
  "admin/pages.editor.locale.kw": "Córnico",
  "admin/pages.editor.locale.ky": "Kirguís",
  "admin/pages.editor.locale.la": "Latín",
  "admin/pages.editor.locale.lb": "Luxemburgués",
  "admin/pages.editor.locale.lg": "Ganda",
  "admin/pages.editor.locale.li": "Limburgués",
  "admin/pages.editor.locale.ln": "Lingala",
  "admin/pages.editor.locale.lo": "Lao",
  "admin/pages.editor.locale.lt": "Lituano",
  "admin/pages.editor.locale.lu": "Luba-katanga",
  "admin/pages.editor.locale.lv": "Letón",
  "admin/pages.editor.locale.mg": "Malgache",
  "admin/pages.editor.locale.mh": "Marshalés",
  "admin/pages.editor.locale.mi": "Maorí",
  "admin/pages.editor.locale.mk": "Macedonio",
  "admin/pages.editor.locale.ml": "Malabar",
  "admin/pages.editor.locale.mn": "Mongol",
  "admin/pages.editor.locale.mr": "Maratí",
  "admin/pages.editor.locale.ms": "Malayo",
  "admin/pages.editor.locale.mt": "Maltés",
  "admin/pages.editor.locale.my": "Birmano",
  "admin/pages.editor.locale.na": "Nauruano",
  "admin/pages.editor.locale.nb": "Noruego bokmal",
  "admin/pages.editor.locale.nd": "Ndebele septentrional",
  "admin/pages.editor.locale.ne": "Nepalí",
  "admin/pages.editor.locale.ng": "Ndonga",
  "admin/pages.editor.locale.nl": "Neerlandés",
  "admin/pages.editor.locale.nn": "Noruego nynorsk",
  "admin/pages.editor.locale.no": "Noruego",
  "admin/pages.editor.locale.nr": "Ndebele meridional",
  "admin/pages.editor.locale.nv": "Navajo",
  "admin/pages.editor.locale.ny": "Nyanja",
  "admin/pages.editor.locale.oc": "Occitano",
  "admin/pages.editor.locale.oj": "Ojibwa",
  "admin/pages.editor.locale.om": "Oromo",
  "admin/pages.editor.locale.or": "Oriya",
  "admin/pages.editor.locale.os": "Osético",
  "admin/pages.editor.locale.pa": "Punyabí",
  "admin/pages.editor.locale.pi": "Pali",
  "admin/pages.editor.locale.pl": "Polaco",
  "admin/pages.editor.locale.ps": "Pastún",
  "admin/pages.editor.locale.pt": "Portugués",
  "admin/pages.editor.locale.qu": "Quechua",
  "admin/pages.editor.locale.rm": "Romanche",
  "admin/pages.editor.locale.rn": "Rundi",
  "admin/pages.editor.locale.ro": "Rumano",
  "admin/pages.editor.locale.ru": "Ruso",
  "admin/pages.editor.locale.rw": "Kinyarwanda",
  "admin/pages.editor.locale.sa": "Sánscrito",
  "admin/pages.editor.locale.sc": "Sardo",
  "admin/pages.editor.locale.sd": "Sindhi",
  "admin/pages.editor.locale.se": "Sami septentrional",
  "admin/pages.editor.locale.sg": "Sango",
  "admin/pages.editor.locale.si": "Cingalés",
  "admin/pages.editor.locale.sk": "Eslovaco",
  "admin/pages.editor.locale.sl": "Esloveno",
  "admin/pages.editor.locale.sm": "Samoano",
  "admin/pages.editor.locale.sn": "Shona",
  "admin/pages.editor.locale.so": "Somalí",
  "admin/pages.editor.locale.sq": "Albanés",
  "admin/pages.editor.locale.sr": "Serbio",
  "admin/pages.editor.locale.ss": "Suazi",
  "admin/pages.editor.locale.st": "Sotho meridional",
  "admin/pages.editor.locale.su": "Sundanés",
  "admin/pages.editor.locale.sv": "Sueco",
  "admin/pages.editor.locale.sw": "Suajili",
  "admin/pages.editor.locale.ta": "Tamil",
  "admin/pages.editor.locale.te": "Telugu",
  "admin/pages.editor.locale.tg": "Tayiko",
  "admin/pages.editor.locale.th": "Tailandés",
  "admin/pages.editor.locale.ti": "Tigriña",
  "admin/pages.editor.locale.tk": "Turcomano",
  "admin/pages.editor.locale.tl": "Tagalo",
  "admin/pages.editor.locale.tn": "Setsuana",
  "admin/pages.editor.locale.to": "Tongano",
  "admin/pages.editor.locale.tr": "Turco",
  "admin/pages.editor.locale.ts": "Tsonga",
  "admin/pages.editor.locale.tt": "Tártaro",
  "admin/pages.editor.locale.tw": "Twi",
  "admin/pages.editor.locale.ty": "Tahitiano",
  "admin/pages.editor.locale.ug": "Uigur",
  "admin/pages.editor.locale.uk": "Ucraniano",
  "admin/pages.editor.locale.ur": "Urdu",
  "admin/pages.editor.locale.uz": "Uzbeko",
  "admin/pages.editor.locale.ve": "Venda",
  "admin/pages.editor.locale.vi": "Vietnamita",
  "admin/pages.editor.locale.vo": "Volapük",
  "admin/pages.editor.locale.wa": "Valón",
  "admin/pages.editor.locale.wo": "Wólof",
  "admin/pages.editor.locale.xh": "Xhosa",
  "admin/pages.editor.locale.yi": "Yidis",
  "admin/pages.editor.locale.yo": "Yoruba",
  "admin/pages.editor.locale.za": "Zhuang",
  "admin/pages.editor.locale.zh": "Chino",
  "admin/pages.editor.locale.zu": "Zulú",
  "admin/pages.editor.store.settings.advanced.disclaimer": "⚠ Estas funcionalidades deben usarse con atención.",
  "admin/pages.editor.store.settings.error.title": "Se produjo un error",
  "admin/pages.editor.store.settings.error": "No se pudo cargar la configuración de la tienda.",
  "admin/pages.editor.store.settings.pwa.android-logo-icon": "Icono del logotipo Android (512x512, PNG)",
  "admin/pages.editor.store.settings.pwa.app-settings": "Otras configuraciones de PWA",
  "admin/pages.editor.store.settings.pwa.background_color": "Color de fondo",
  "admin/pages.editor.store.settings.pwa.disable-prompt": "Agregar a la pantalla de inicio",
  "admin/pages.editor.store.settings.pwa.display.browser": "Navegador",
  "admin/pages.editor.store.settings.pwa.display.fullscreen": "Pantalla completa",
  "admin/pages.editor.store.settings.pwa.display.minimal-ui": "UI minimalista (no admitida por Chrome)",
  "admin/pages.editor.store.settings.pwa.display.standalone": "Independiente (agregar a la pantalla de inicio)",
  "admin/pages.editor.store.settings.pwa.display": "Visualización",
  "admin/pages.editor.store.settings.pwa.error": "No se pudo cargar la configuración de PWA.",
  "admin/pages.editor.store.settings.pwa.ios-logo-icon": "Icono de logotipo iOS (512x512, PNG)",
  "admin/pages.editor.store.settings.pwa.orientation.any": "Cualquier",
  "admin/pages.editor.store.settings.pwa.orientation.landscape-primary": "Horizontal (primaria)",
  "admin/pages.editor.store.settings.pwa.orientation.landscape-secondary": "Horizontal (secundaria)",
  "admin/pages.editor.store.settings.pwa.orientation.landscape": "Horizontal",
  "admin/pages.editor.store.settings.pwa.orientation.natural": "Natural",
  "admin/pages.editor.store.settings.pwa.orientation.portrait-primary": "Vertical (primaria)",
  "admin/pages.editor.store.settings.pwa.orientation.portrait-secondary": "Vertical (secundaria)",
  "admin/pages.editor.store.settings.pwa.orientation.portrait": "Vertical",
  "admin/pages.editor.store.settings.pwa.prompt-custom-event.addToCart": "En el primer ítem agregado al carrito",
  "admin/pages.editor.store.settings.pwa.prompt-custom-event.checkout": "En la primera compra",
  "admin/pages.editor.store.settings.pwa.prompt-custom-event.default": "En la primera visita",
  "admin/pages.editor.store.settings.pwa.prompt-custom-event": "Aviso \"Agregar a la pantalla de inicio\"",
  "admin/pages.editor.store.settings.pwa.screen-orientation": "Orientación de la pantalla",
  "admin/pages.editor.store.settings.pwa.splash-screen": "Vista previa de la pantalla de presentación (iOS)",
  "admin/pages.editor.store.settings.pwa.start_url": "URL de inicio",
  "admin/pages.editor.store.settings.pwa.theme_color": "Color del tema",
  "admin/pages.editor.store.settings.pwa.update-manifest-icon.error": "Se produjo un error al actualizar el icono de la aplicación…",
  "admin/pages.editor.store.settings.pwa.update-manifest-icon.success": "¡El ícono de la aplicación se actualizó con éxito!",
  "admin/pages.editor.store.settings.refetch": "Reintentar",
  "admin/pages.editor.store.settings.tabs.advanced": "Avanzado",
  "admin/pages.editor.store.settings.tabs.general": "General",
  "admin/pages.editor.store.settings.tabs.pwa": "PWA",
  "admin/pages.editor.store.settings.title": "Configuración de la tienda",
  "admin/pages.editor.styles.card.current": "Actual",
  "admin/pages.editor.styles.card.menu.delete.fail": "No se pudo eliminar el estilo.",
  "admin/pages.editor.styles.card.menu.delete": "Eliminar",
  "admin/pages.editor.styles.card.menu.duplicate.fail": "No se pudo duplicar el estilo '{name}'.",
  "admin/pages.editor.styles.card.menu.duplicate.success": "Estilo '{name}' duplicado con éxito.",
  "admin/pages.editor.styles.card.menu.duplicate": "Duplicar",
  "admin/pages.editor.styles.card.menu.edit": "Editar",
  "admin/pages.editor.styles.card.menu.select": "Seleccionar como estilo de la tienda",
  "admin/pages.editor.styles.card.name.app-subtitle": "creado por {app}",
  "admin/pages.editor.styles.duplicate.defaultName": "Copia de {name}",
  "admin/pages.editor.styles.edit.colors.title": "Colores",
  "admin/pages.editor.styles.edit.custom-font.file-link": "Link del archivo",
  "admin/pages.editor.styles.edit.custom-font.file-upload": "Cargar un archivo",
  "admin/pages.editor.styles.edit.custom-font.style": "Estilo:",
  "admin/pages.editor.styles.edit.custom-font.title": "Fuente personalizada",
  "admin/pages.editor.styles.edit.custom-font.upload-description-max-size": "(Tamaño máximo: 2MB)",
  "admin/pages.editor.styles.edit.custom-font.upload-description": "Carga tus archivos de familias de fuentes en formato .ttf o .woff.",
  "admin/pages.editor.styles.edit.custom-font.upload": "Cargar",
  "admin/pages.editor.styles.edit.font-family.add-font-description": "Puedes agregar familias de fuentes personalizadas a tu tienda. ¿Vamos a agregar algunas?",
  "admin/pages.editor.styles.edit.font-family.add-font-success": "Familia de fuentes guardada con éxito.",
  "admin/pages.editor.styles.edit.font-family.add-font": "Agregar fuente personalizada",
  "admin/pages.editor.styles.edit.font-family.remove-font-failure": "No se puede eliminar la familia de fuentes porque algún estilo lo utiliza.",
  "admin/pages.editor.styles.edit.font-family.remove-font-success": "Familia de fuentes eliminada con éxito.",
  "admin/pages.editor.styles.edit.font-family.style-dropdown-placeholder": "Elige un estilo",
  "admin/pages.editor.styles.edit.font-family.title": "Familia de fuentes",
  "admin/pages.editor.styles.edit.save.failed": "Se produjo un error al guardar tu estilo.",
  "admin/pages.editor.styles.edit.save.successful": "Estilo guardado con éxito.",
  "admin/pages.editor.styles.edit.type-tokens.title": "Tokens de tipo",
  "admin/pages.editor.styles.edit.typography.title": "Tipografía",
  "admin/pages.editor.styles.header.title": "Estilos",
  "admin/pages.editor.styles.new-button.text": "Nuevo",
  "admin/pages.editor.styles.new.defaultName": "Sin título",
  "admin/pages.editor.styles.new.fail": "No se pudo crear el nuevo estilo.",
  "admin/pages.editor.styles.new.success": "Nuevo estilo creado.",
  "admin/pages.editor.styles.select.delete-success": "Se eliminó el estilo '{name}'.",
  "admin/pages.editor.styles.select.delete.toast.undo": "Deshacer",
  "admin/pages.editor.styles.select.save-fail": "No se pudo seleccionar el estilo '{name}'.",
  "admin/pages.editor.styles.select.save-success": "Estilo '{name}' seleccionado.",
  "admin/pages.editor.topbar.button.block-picker.tooltip": "Selecciona un bloque",
  "admin/pages.editor.topbar.button.device.desktop.tooltip": "Vista de escritorio",
  "admin/pages.editor.topbar.button.device.mobile.tooltip": "Vista móvil",
  "admin/pages.editor.topbar.button.device.tablet.tooltip": "Vista de tablet",
  "admin/pages.editor.topbar.button.preview.tooltip": "Vista previa",
  "admin/pages.editor.topbar.context.binding.error": "No se pudo cargar la lista de vínculos disponibles.",
  "admin/pages.editor.topbar.context.binding.tooltip": "No se puede cambiar el vínculo mientras se edita un bloque.",
  "admin/pages.editor.topbar.context.locale.tooltip": "No se puede cambiar el idioma mientras se edita un bloque.",
  "admin/appframe.navigation.contentManagement": "Gestión de contenido",
  "admin/pages.admin.redirects.upload-modal.prompt.alert.missing-binding-data": "Falta información de vinculación para la redirección {route}",
  "admin/pages.admin.redirects.upload-modal.prompt.alert.extra-binding-data": "Información de vinculación innecesaria en la redirección {route}",
  "admin/store.b2benabled.title": "Comportamiento B2B activado",
  "admin/store.title": "Tienda VTEX",
  "admin/store.storeName.title": "Nombre de la tienda",
  "admin/store.requiresAuthorization.title": "Habilita el comportamiento B2B",
  "admin/store.titleTag.title": "Tag de título predeterminada",
  "admin/store.metaTagDescription.title": "Tag de metadescripción",
  "admin/store.metaTagRobots.title": "Tag de robots meta",
  "admin/store.metaTagRobots.description": "Valor predeterminado: index, follow",
  "admin/store.faviconLinks.title": "Faviconos",
  "admin/store.faviconLinks.rel.title": "Relación del favicono",
  "admin/store.faviconLinks.rel.description": "Esta relación del favicono. Ejemplo: \"icon\", \"shortcut icon\", \"apple-touch-icon\"",
  "admin/store.faviconLinks.type.title": "Tipo de multimedia del favicono",
  "admin/store.faviconLinks.type.description": "(Opcional) Tipo de favicono. Ejemplo: image/png",
  "admin/store.faviconLinks.sizes.title": "Tamaño del favicono",
  "admin/store.faviconLinks.sizes.description": "(Opcional) Tamaño del favicono en formato: {anchura}x{altura}. Ejemplo: 180x180",
  "admin/store.faviconLinks.href.title": "Href del favicono",
  "admin/store.faviconLinks.description": "Configura los faviconos de tu tienda",
  "admin/store.searchTermPath.title": "Ruta del término de búsqueda",
  "admin/store.searchTermPath.description": "Indica la ruta de búsqueda de tu tienda",
  "admin/store.advancedSettings.title": "Configuración avanzada de la tienda",
  "admin/store.advancedSettings.enableOrderFormOptimization.title": "Optimización de orderForm",
  "admin/store.advancedSettings.enableOrderFormOptimization.description": "Desactiva el proveedor heredado de OrderForm. Más información en: https://vtex.io/docs/recipes/store-management/enabling-order-form-optimization.",
  "admin/store.advancedSettings.enableServiceWorker.title": "Service Worker",
  "admin/store.advancedSettings.enableServiceWorker.description": "Registra el Service Worker predeterminado proporcionado por VTEX.",
  "admin/store.advancedSettings.enableCriticalCSS.title": "Optimización de CSS crítico",
  "admin/store.advancedSettings.enableCriticalCSS.description": "Habilita las optimizaciones de CSS que pueden mejorar el rendimiento y la puntuación de Lighthouse. Solo afecta la página de inicio. Puede ocasionar inconsistencias de estilo. Prueba con precaución después de activarlo.",
  "admin/store.advancedSettings.enableCriticalCSSOnSearch.title": "Optimización de CSS crítico en la página de búsqueda",
  "admin/store.advancedSettings.enableCriticalCSSOnSearch.description": "Habilita las optimizaciones de CSS que pueden mejorar el rendimiento y la puntuación de Lighthouse. Solo afecta la página de búsqueda. Puede ocasionar inconsistencias de estilo. Prueba con precaución después de activarlo.",
  "admin/store.advancedSettings.enableCriticalCSSOnCustom.title": "Optimización de CSS crítico en la página personalizada",
  "admin/store.advancedSettings.enableCriticalCSSOnCustom.description": "Habilita las optimizaciones de CSS que pueden mejorar el rendimiento y la puntuación de Lighthouse. Solo afecta las páginas personalizadas. Puede ocasionar inconsistencias de estilo. Prueba con precaución después de activarlo.",
  "admin/store.advancedSettings.enableCriticalCSSOnProduct.title": "Optimización de CSS crítico en la página del producto",
  "admin/store.advancedSettings.enableCriticalCSSOnProduct.description": "Habilita las optimizaciones de CSS que pueden mejorar el rendimiento y la puntuación de Lighthouse. Solo afecta las páginas de producto. Puede ocasionar inconsistencias de estilo. Prueba con precaución después de activarlo.",
  "admin/store.advancedSettings.enableCSSConcatenation.title": "Habilita la concatenación de CSS",
  "admin/store.advancedSettings.enableCSSConcatenation.description": "Concatena el CSS de una página en un solo archivo para una descarga más rápida.",
  "admin/store.advancedSettings.enablePrefetch.title": "Habilita la captura previa",
  "admin/store.advancedSettings.enablePrefetch.description": "Precarga las páginas cuando se pasa el mouse para una navegación más rápida.",
  "admin/store.advancedSettings.enableLazyRuntime.title": "Habilita la ejecución de carga lazy",
  "admin/store.advancedSettings.enableLazyRuntime.description": "Carga lentamente los metadatos de la página.",
  "admin/store.advancedSettings.enableMenuRenderingOptimization.title": "Habilita la renderización lazy de los ítems del submenú",
  "admin/store.advancedSettings.enableMenuRenderingOptimization.description": "Permite la renderización optimizada del submenú, lo que mejora el rendimiento. Puede causar problemas de estilo. Prueba con precaución después de activarlo.",
  "admin/store.advancedSettings.enableSearchRenderingOptimization.title": "Habilita la renderización lazy de los resultados de búsqueda y facetas",
  "admin/store.advancedSettings.enableSearchRenderingOptimization.description": "Habilita la renderización de los resultados de búsqueda y facetas, lo que mejora el rendimiento. Puede ocasionar inconsistencias de estilo. Prueba con precaución después de activarlo.",
  "admin/store.advancedSettings.enableAsyncScripts.title": "Habilita la carga asíncrona de scripts",
  "admin/store.advancedSettings.enableAsyncScripts.description": "Inicia el procesamiento de scripts antes cargándolos y ejecutándolos de forma asíncrona.",
  "admin/store.advancedSettings.enableConcurrentMode.title": "Activar el modo concurrente de React",
  "admin/store.advancedSettings.enableConcurrentMode.description": "Ayuda a la tienda a mantenerse responsiva y a ajustarse a la capacidad del dispositivo y a la velocidad de internet del usuario.",
  "admin/store.advancedSettings.enableFiltersFetchOptimization.title": "Activa la búsqueda de filtros parcial",
  "admin/store.advancedSettings.enableFiltersFetchOptimization.description": "Mejora el rendimiento de las páginas de búsqueda cargando solo las 10 primeras facetas de cada filtro, agregando un botón para mostrar el resto. Puede causar problemas al ir a una página que tenga facetas seleccionadas, especialmente en search-resolver v0. Prueba con precaución después de activar esta opción.",
  "admin/store.advancedSettings.enableFullSSROnProduct.title": "Activar la ejecución de todas las consultas GraphQL en la página de producto",
  "admin/store.advancedSettings.enableFullSSROnProduct.description": "Ayuda cuando una página de producto necesita obtener datos adicionales para renderizar componentes en la mitad inferior de la página. Actívalo solo si tu página de producto realmente lo necesita, de lo contrario afectará negativamente el rendimiento.",
  "admin/store.advancedSettings.enableLazyFooter.title": "Activar la renderización lazy del pie de página",
  "admin/store.advancedSettings.enableLazyFooter.description": "Renderiza de forma lenta el pie de página y la carga de sus activos, lo que ayuda a mejorar el rendimiento de la primera renderización de la página.",
  "admin/store.advancedSettings.enableLazyFold.title": "Habilitar la carga lazy de los activos en la mitad inferior de la página",
  "admin/store.advancedSettings.enableLazyFold.description": "Habilita la carga lazy de los archivos JS de los componentes del bloque debajo del border `__fold__`.",
  "admin/store.advancedSettings.fetchSponsoredProductsOnSearch.title": "[BETA] Obtenga productos patrocinados en los resultados de búsqueda.",
  "admin/store.advancedSettings.fetchSponsoredProductsOnSearch.description": "Si esta tienda tiene configurado VTEX Ads, esta opción buscará productos patrocinados en los resultados de búsqueda.",
  "admin/pages.editor.newadmin.alert": "Este es un entorno de prueba. Para aplicar cambios a tu tienda online, ",
  "admin/pages.editor.newadmin.alert.anchor": "por favor accede al Admin VTEX anterior.",
  "admin/store.includeTwitterMetaTags.title": "Incluir meta tags de Twitter",
  "admin/store.twitterUsername.title": "Nombre de usuario de Twitter",
  "admin/store.twitterUsername.description": "El nombre de usuario que tu empresa utiliza en Twitter. Por ejemplo: VTEXcommerce.",
  "admin/store.twitterCard.title": "Twitter card",
  "admin/store.twitterCard.description": "Por favor, elige el tipo de Twitter card",
  "admin/store.advancedSettings.enablePageNumberTitle.title": "Activar número de página en el metatítulo",
  "admin/store.advancedSettings.enablePageNumberTitle.description": "Agrega un #{Número} al final del título para evitar el problema de la duplicación de títulos",
  "admin/store.advancedSettings.canonicalWithoutUrlParams.title": "URL canónica sin parámetros de URL",
  "admin/store.advancedSettings.canonicalWithoutUrlParams.description": "Remueve el parámetro de mapa de la URL canónica. Esto puede causar problemas al acceder a una página con facetas seleccionadas. Prueba con precaución después de activarlo.",
  "admin/store.advancedSettings.removeStoreNameTitle.title": "Remover el nombre de la tienda del título",
  "admin/store.advancedSettings.removeStoreNameTitle.description": "Remover el nombre de la tienda al final de los metatítulos de productos y categorías",
  "admin/store.advancedSettings.enableCustomCurrencySymbol.title": "Habilitar el uso de un símbolo de moneda personalizado",
  "admin/store.advancedSettings.enableCustomCurrencySymbol.description": "Usa el campo \"Símbolo de la moneda\" definido en la política comercial",
  "admin/pages.editor.copy-page.modal.header": "Clonar página a otros vínculos",
  "admin/pages.editor.copy-page.modal.subheader": "Elige a qué vínculos se duplicará el contenido. Si la página no existe en un vínculo, se creará y los metadatos (como la información SEO) también serán copiados.",
  "admin/pages.editor.copy-page.modal.error.title": "Error al obtener información de rutas",
  "admin/pages.editor.copy-page.modal.error.body": "Se produjo un error al recuperar la información de las rutas. Por favor, intenta cerrar y volver a abrir el modal.",
  "admin/pages.editor.copy-page.modal.table-header.supported-locales": "Regiones soportadas",
  "admin/pages.editor.copy-page.modal.table-header.warning": "Aviso",
  "admin/pages.editor.copy-page.modal.warning.page-exists": "La página ya existe",
  "admin/pages.editor.topbar.button.copy-page.tooltip": "Clonar página a otros vínculos",
  "admin/pages.editor.components.button.go-back": "Volver",
  "admin/pages.editor.components.button.overwrite": "Sobrescribir",
  "admin/pages.editor.copy-page.overwritedialog.header": "El contenido existente se sobrescribirá",
  "admin/pages.editor.copy-page.overwritedialog.subheader.singular": "El contenido existente en estos vínculos se eliminará permanentemente:",
  "admin/pages.editor.copy-page.overwritedialog.subheader.plural": "El contenido existente en este vínculo se eliminará permanentemente:",
  "admin/pages.editor.copy-page.overwritedialog.confirmation": "¿Estás seguro de que deseas duplicar el contenido?",
  "admin/pages.editor.copy-page.modal.toast.saving": "Guardando...",
  "admin/pages.editor.copy-page.modal.toast.success": "¡Listo!",
  "admin/pages.editor.copy-page.modal.toast.error": "Se produjo un error. Por favor, vuelve a intentarlo.",
  "admin/actions.enable-binding": "Activar la configuración por vinculación",
  "admin/actions.binding-configurations": "Configuración de vinculación",
  "admin/actions.binding-id": "ID de vínculo",
  "admin/actions.binding-description": "Introduce el ID de vínculo",
  "admin/store.advancedSettings.customHeader.title": "Encabezados personalizados",
  "admin/store.advancedSettings.customHeader.__editorItemTitle.title": "ID del encabezado",
  "admin/store.advancedSettings.customHeader.__editorItemTitle.description": "Ingresa el ID para identificar tu encabezado. Ejemplo: Nuevo encabezado personalizado",
  "admin/store.advancedSettings.customHeader.key.title": "Clave del encabezado",
  "admin/store.advancedSettings.customHeader.key.description": "Ingresa la clave de tu encabezado, en formato HTTP. Ejemplo: Strict-Transport-Security",
  "admin/store.advancedSettings.customHeader.value.title": "Valor del encabezado",
  "admin/store.advancedSettings.customHeader.value.description": "Ingresa el valor de tu clave, en formato HTTP. Ejemplo: max-age=<expire-time>",
  "admin/store.advancedSettings.a11ySemanticHtmlMigration.title": "Activar migración a HTML semántico para accesibilidad",
  "admin/store.advancedSettings.a11ySemanticHtmlMigration.description": "Activa elementos HTML semánticos para mejorar la accesibilidad y garantizar el cumplimiento de la Ley Europea de Accesibilidad (EAA) y WCAG 2.1. Esto puede provocar cambios que impacten los estilos personalizados que dependen de elementos HTML específicos."
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of admin-pages/admin/navigation.json from the admin-pages VTEX app.

[Assistant]
Here's the implementation:

```json
[
  {
    "section": "storeSetup",
    "LMProductId": "38",
    "subSection": "cms",
    "subSectionItems": [
      {
        "isNew": true,
        "labelId": "admin/pages.admin-menu-button.pages",
        "path": "/admin/cms/pages"
      },
      {
        "isNew": true,
        "labelId": "admin/pages.admin-menu-button.site-editor",
        "path": "/admin/cms/site-editor"
      },
      {
        "isNew": true,
        "labelId": "admin/pages.admin-menu-button.styles",
        "path": "/admin/cms/styles"
      },
      {
        "isNew": true,
        "labelId": "admin/pages.admin-menu-button.store",
        "path": "/admin/cms/store"
      }
    ]
  },
  {
    "section": "gocommerce",
    "LMProductId": "38",
    "subSection": "onlinestore",
    "subSectionItems": [
      {
        "labelId": "admin/pages.admin-menu-button.site-editor-smb",
        "path": "/admin/cms/site-editor"
      },
      {
        "labelId": "admin/pages.admin-menu-button.styles",
        "path": "/admin/cms/styles"
      },
      {
        "labelId": "admin/pages.admin-menu-button.pages",
        "path": "/admin/cms/content"
      }
    ]
  },
  {
    "section": "storeFront",
    "LMProductId": "38",
    "adminVersion": 4,
    "subSection": "contentManagement",
    "titleId": "admin/appframe.navigation.contentManagement",
    "subSectionItems": [
      {
        "position": {
          "index": 0,
          "operation": "add"
        },
        "labelId": "admin/pages.admin-menu-button.site-editor",
        "path": "/admin/cms/site-editor"
      },
      {
        "labelId": "admin/pages.admin-menu-button.pages",
        "path": "/admin/cms/pages"
      },
      {
        "labelId": "admin/pages.admin-menu-button.styles",
        "path": "/admin/cms/styles"
      },
      {
        "labelId": "admin/pages.admin.tabs.redirects",
        "path": "/admin/cms/redirects"
      }
    ]
  },
  {
    "section": "storeSettings",
    "LMProductId": "38",
    "subSection": "storeFront",
    "adminVersion": 4,
    "subSectionItems": [
      {
        "labelId": "admin/pages.admin-menu-button.store",
        "path": "/admin/cms/store"
      }
    ]
  }
]

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of admin-pages/admin/routes.json from the admin-pages VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin.app.cms": {
    "around": ["wrapper"]
  },
  "admin.app.cms.pages": {
    "around": ["pages-wrapper"]
  },
  "admin.app.cms.pages.page-list": {
    "component": "PageListWrapper",
    "path": "/admin/app/cms/pages"
  },
  "admin.app.cms.pages.page-details": {
    "component": "PageFormWrapper",
    "path": "/admin/app/cms/pages/*id"
  },
  "admin.app.cms.pages.redirects": {
    "component": "RedirectListWrapper",
    "path": "/admin/app/cms/redirects"
  },
  "admin.app.cms.pages.redirect-details": {
    "component": "RedirectForm",
    "path": "/admin/app/cms/redirects/*path"
  },
  "admin.app.cms.content": {
    "component": "InstitutionalPageList",
    "path": "/admin/app/cms/content"
  },
  "admin.app.cms.content-details": {
    "component": "InstitutionalPageForm",
    "path": "/admin/app/cms/content/*id"
  },
  "admin.app.cms.site-editor-home": {
    "component": "PageEditor",
    "path": "/admin/app/cms/site-editor"
  },
  "admin.app.cms.site-editor": {
    "component": "PageEditor",
    "path": "/admin/app/cms/site-editor/*targetPath"
  },
  "admin.app.cms.storefront-home": {
    "component": "PageEditor",
    "path": "/admin/app/cms/storefront"
  },
  "admin.app.cms.storefront": {
    "component": "PageEditor",
    "path": "/admin/app/cms/storefront/*targetPath"
  },
  "admin.app.cms.styles": {
    "component": "PageEditor",
    "path": "/admin/app/cms/styles"
  },
  "admin.app.cms.store": {
    "component": "StoreSettings",
    "path": "/admin/app/cms/store"
  },
  "highlight-overlay.cms": {
    "component": "HighlightOverlay",
    "extensible": "vtex",
    "render": "lazy"
  },
  "pages-wrapper": {
    "component": "PagesAdminWrapper"
  },
  "wrapper": {
    "component": "Wrapper"
  },
  "admin.app.cms.media-gallery": {
    "component": "MediaGalleryWidget",
    "path": "/admin/app/cms/media-gallery-widget"
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of admin-pages/docs/README.md from the admin-pages VTEX app.

[Assistant]
Here's the implementation:

```markdown
# VTEX Pages Admin

The Pages Admin is a platform to dynamically edit a VTEX Store, making it possible to select editable components and change its configurations adding or removing content in a straightforward way.

## Continuous Integrations

### Travis CI

[![Build Status](https://travis-ci.org/vtex-apps/pages-editor.svg?branch=master)](https://travis-ci.org/vtex-apps/pages-editor)

## How to make your Component editable

The editor supports two ways of defining an editable component, thought a static schema structure or a dynamic function, that receives data and create the schema to be displayed.

### Static Schema

Add to your component an `schema` constant, a JSON object that with the following structure:

```javascript
const schema = {
  type: 'object',
  title: 'The component title',
  properties: {
    property1: {
      type: 'string'
      title: 'Title of the property'
    },
    ...{n* properties}
  }
}
```

The property type can be: `String`, `Object` or `Number`, if `Object` it will have the same structure as the parent properties.

### Dynamic Schema

Add to your component a function `getSchema`, that will have the logic to dynamically create the schema need to build your component structure. The Page Editor will call that function each time that the page form has a change to its state, which enables to add and remove fields from the schema, like the example below.

```javascript
import { range, map, clone, indexBy, prop } from 'ramda'

const bannerStructure = {
  type: 'object',
  title: 'banner',
  properties: {
    image: {
      type: 'string',
      title: 'Banner image',
    },
    page: {
      type: 'string',
      title: 'Banner link',
    },
    targetParams: {
      type: 'object',
      title: 'Banner target params',
      properties: {
        params: {
          type: 'string',
          title: 'Params',
        },
      },
    },
  },
}

static getSchema = ({numberOfBanners}) => {
  // Do a for loop replicating the banner structure, to create n* banners
  const getRepeatedProperties = (repetition) => indexBy(prop('title'), map((index) => {
    const property = clone(bannerStructure)
    property.title = `${property.title}${index}`
    return property
  }, range(1, repetition+1)))

  // Call's the function if the numberOfBanners its passed
  const generatedSchema = numberOfBanners && getRepeatedProperties(numberOfBanners)

  /**
  * Returns a schema embedding the generated properties and the static property needed
  * to type the number of banners wanted.
  */
  return {
    type: 'object',
    properties: {
      numberOfBanners: {
        type: 'number',
        title: 'Number of banners'
      },
      ...generatedSchema
    }
  }
}
```

## Custom Content Pages

See [docs](https://github.com/vtex-apps/admin-pages/blob/master/docs/CONTENT_PAGE.md)

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of admin-pages/pages/plugins.json from the admin-pages VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "storeWrapper > highlight-overlay": "highlight-overlay.cms"
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of admin-pages/react/EditableExtensionPoint.tsx from the admin-pages VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'

interface Props {
  children?: React.ReactNode
}

// Backwards compatibility, we can delete this file upon releasing the next render-runtime.
const EditableExtensionPoint = ({ children }: Props) => children || null

export default EditableExtensionPoint

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of admin-pages/react/RedirectForm.tsx from the admin-pages VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Component } from 'react'
import { withApollo, WithApolloClient } from 'react-apollo'
import {
  injectIntl,
  WrappedComponentProps as ComponentWithIntlProps,
} from 'react-intl'
import { Helmet, withRuntimeContext } from 'vtex.render-runtime'
import { Box, ToastConsumer } from 'vtex.styleguide'
import { Binding, Tenant } from 'vtex.tenant-graphql'
import queryString from 'query-string'

import {
  BASE_URL,
  NEW_REDIRECT_ID,
  WRAPPER_PATH,
} from './components/admin/redirects/consts'
import Form from './components/admin/redirects/Form'
import Operations from './components/admin/redirects/Form/Operations'
import { RedirectQuery } from './components/admin/redirects/Form/typings'
import {
  TargetPathContextProps,
  withTargetPath,
} from './components/admin/TargetPathContext'
import Loader from './components/Loader'
import Redirect from './queries/Redirect.graphql'
import TenantInfoQuery from './queries/TenantInfo.graphql'
import { getStoreBindings } from './utils/bindings'

interface CustomProps {
  params: {
    path: string
  }
}

type Props = WithApolloClient<
  CustomProps &
    RenderContextProps &
    ComponentWithIntlProps &
    TargetPathContextProps
>

interface State {
  formData?: Redirect
  isLoading: boolean
  storeBindings: Binding[] | null
  isNew: boolean
}

class RedirectForm extends Component<Props, State> {
  public constructor(props: Props) {
    super(props)

    const defaultFormData = {
      endDate: null,
      from: '',
      to: '',
      type: 'PERMANENT' as RedirectTypes,
      binding: '',
    }

    const isNew = props.params.path === NEW_REDIRECT_ID

    this.state = {
      formData: isNew ? defaultFormData : undefined,
      isLoading: isNew ? false : true,
      storeBindings: null,
      isNew,
    }
  }

  public async componentDidMount() {
    const {
      client,
      params,
      runtime: { navigate, history },
      setTargetPath,
    } = this.props
    const { formData } = this.state

    setTargetPath(WRAPPER_PATH)
    // Get tenant info
    const { data } = await client.query<{ tenantInfo: Tenant }, {}>({
      query: TenantInfoQuery,
    })
    const tenantInfo = data?.tenantInfo
    if (!tenantInfo) {
      throw Error()
    }
    const storeBindings = getStoreBindings(tenantInfo)
    this.setState({
      storeBindings,
    })

    if (!formData) {
      try {
        const rawQuerystring = history?.location?.search ?? ''
        const querystring = queryString.parse(rawQuerystring)
        const { binding, ...rest } = querystring
        const restQuerystring = queryString.stringify(rest)
        const response = await client.query<RedirectQuery>({
          query: Redirect,
          variables: {
            path: `/${params.path}${
              restQuerystring ? '?' + restQuerystring : ''
            }`,
            binding: binding,
          },
        })

        const redirectInfo = response.data.redirect.get
        if (redirectInfo) {
          this.setState({
            formData: redirectInfo,
            isLoading: false,
          })
        } else {
          console.warn('Invalid path. Navigating to redirect list...')

          navigate({ to: BASE_URL })
        }
      } catch (err) {
        console.error(err)

        navigate({ to: BASE_URL })
      }
    } else {
      if (!formData.binding) {
        formData.binding = storeBindings[0].id
        this.setState({
          formData,
        })
      }
    }
  }

  public render() {
    const { intl, params } = this.props
    const { formData, isLoading, storeBindings, isNew } = this.state

    return (
      <>
        <Helmet>
          <title>
            {intl.formatMessage({
              id:
                params.path === NEW_REDIRECT_ID
                  ? 'admin/pages.admin.redirects.form.title.new'
                  : 'admin/pages.admin.redirects.form.title.info',
            })}
          </title>
        </Helmet>
        <Operations>
          {({ deleteRedirect, saveRedirect }) =>
            isLoading ? (
              <Loader />
            ) : (
              <ToastConsumer>
                {({ showToast }) => (
                  <Box>
                    <Form
                      initialData={formData as Redirect}
                      onDelete={deleteRedirect}
                      onSave={saveRedirect}
                      showToast={showToast}
                      storeBindings={storeBindings}
                      isNew={isNew}
                    />
                  </Box>
                )}
              </ToastConsumer>
            )
          }
        </Operations>
      </>
    )
  }
}

export default injectIntl(
  withApollo(withRuntimeContext(withTargetPath(RedirectForm)))
)

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of admin-pages/react/PageList.tsx from the admin-pages VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { useEffect, useMemo } from 'react'
import { Query } from 'react-apollo'

import { WRAPPER_PATH } from './components/admin/pages/consts'
import List from './components/admin/pages/List'
import { CategorizedRoutes } from './components/admin/pages/List/typings'
import { isStoreRoute } from './components/admin/pages/utils'
import { useTargetPathContext } from './components/admin/TargetPathContext'
import Loader from './components/Loader'
import RoutesQuery from './queries/Routes.graphql'
import { useAdminLoadingContext } from './utils/AdminLoadingContext'

interface QueryData {
  routes: Route[]
}

interface PageListProps {
  data?: QueryData
  isLoading: boolean
}

const PageListWithQuery = ({ binding }: { binding: string | undefined }) => {
  return (
    <Query<QueryData>
      query={RoutesQuery}
      variables={{ domain: 'store', bindingId: binding }}
    >
      {({ data, loading: isLoading }) => {
        return <PageList isLoading={isLoading} data={data} />
      }}
    </Query>
  )
}

const PageList: React.FunctionComponent<PageListProps> = ({
  data,
  isLoading,
}) => {
  const { startLoading, stopLoading } = useAdminLoadingContext()
  const { setTargetPath } = useTargetPathContext()

  useEffect(() => {
    setTargetPath(WRAPPER_PATH)
  }, [setTargetPath])

  useEffect(() => {
    if (isLoading) {
      startLoading()
    } else {
      stopLoading()
    }
  }, [isLoading, startLoading, stopLoading])

  const categorizedRoutes = useMemo(() => {
    const routes = data && data.routes

    const storeRoutes = routes
      ? routes.filter(route => isStoreRoute(route.domain))
      : []

    return storeRoutes.reduce(
      (acc: CategorizedRoutes, currRoute: Route) => {
        const currRouteContext = currRoute.context || ''

        if (currRoute.interfaceId.endsWith('store.not-found')) {
          return {
            ...acc,
            notFoundSection: [...acc.notFoundSection, currRoute],
          }
        }

        if (currRouteContext.endsWith('ContentPageContext')) {
          return acc
        }

        if (currRouteContext.endsWith('SearchContext')) {
          return {
            ...acc,
            multipleProducts: [...acc.multipleProducts, currRoute],
          }
        }

        if (currRouteContext.endsWith('ProductContext')) {
          return {
            ...acc,
            singleProduct: [...acc.singleProduct, currRoute],
          }
        }

        return { ...acc, noProducts: [...acc.noProducts, currRoute] }
      },
      {
        multipleProducts: [],
        noProducts: [],
        singleProduct: [],
        notFoundSection: [],
      }
    )
  }, [data])

  return !isLoading ? (
    <List categorizedRoutes={categorizedRoutes} />
  ) : (
    <Loader />
  )
}

export default React.memo(PageListWithQuery)

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of admin-pages/react/PageListWrapper.tsx from the admin-pages VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { useMemo, useState } from 'react'
import { Query } from 'react-apollo'
import { Tenant } from 'vtex.tenant-graphql'
import { Dropdown } from 'vtex.styleguide'

import Loader from './components/Loader'
import TenantInfo from './queries/TenantInfo.graphql'
import PageList from './PageList'
import {
  getBindingSelectorOptions,
  getStoreBindings,
  useBinding,
} from './utils/bindings'
import { DropdownChangeInput } from './utils/bindings/typings'

interface PageListWrapperProps {
  tenantInfo: Tenant
}

interface BindingSelectorWrapper {
  visible: boolean
}

const PageListWrapperWithQuery = () => {
  return (
    <Query<{ tenantInfo: Tenant }> query={TenantInfo}>
      {({ data, loading: isLoading }) => {
        const tenantInfo = data?.tenantInfo
        return isLoading || !tenantInfo ? (
          <Loader />
        ) : (
          <PageListWrapper tenantInfo={tenantInfo} />
        )
      }}
    </Query>
  )
}

const BindingSelectorWrapper: React.FunctionComponent<BindingSelectorWrapper> = props => {
  const { children, visible } = props
  return visible ? <div className="flex justify-end pb5">{children}</div> : null
}

const PageListWrapper: React.FunctionComponent<PageListWrapperProps> = ({
  tenantInfo,
}) => {
  const storeBindings = useMemo(() => getStoreBindings(tenantInfo), [
    tenantInfo,
  ])
  // Get Binding from local Storage
  const [localStorageBinding, setLocalStorageBinding] = useBinding()
  const defaultBinding = localStorageBinding || storeBindings[0] // [TODO] Error check here
  const [binding, setSelectedBinding] = useState(defaultBinding)

  const bindingOptions = useMemo(
    () => getBindingSelectorOptions(storeBindings),
    [storeBindings]
  )

  const handleChange = ({ target: { value } }: DropdownChangeInput) => {
    const selectedBinding = storeBindings.find(binding => binding.id === value)
    if (!selectedBinding) {
      throw new Error(
        "Selected binding does not exist or isn't a store binding"
      )
    }
    setSelectedBinding(selectedBinding)
    setLocalStorageBinding(selectedBinding)
  }

  return (
    <div>
      <BindingSelectorWrapper visible={storeBindings.length > 1}>
        <Dropdown
          disabled={storeBindings.length === 1}
          onChange={handleChange}
          options={bindingOptions}
          value={binding.id}
        />
      </BindingSelectorWrapper>
      <PageList binding={binding.id} />
    </div>
  )
}

export default React.memo(PageListWrapperWithQuery)

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of admin-pages/react/RedirectListWrapper.tsx from the admin-pages VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { Query } from 'react-apollo'
import { Tenant } from 'vtex.tenant-graphql'

import Loader from './components/Loader'
import TenantInfo from './queries/TenantInfo.graphql'
import RedirectList from './RedirectList'
import { getStoreBindings } from './utils/bindings'

const RedirectListWrapper = () => {
  return (
    <Query<{ tenantInfo: Tenant }> query={TenantInfo}>
      {({ data, loading: isLoading }) => {
        const tenantInfo = data?.tenantInfo
        if (isLoading || !tenantInfo) {
          return <Loader />
        }
        const storeBindings = getStoreBindings(tenantInfo)
        return <RedirectList hasMultipleBindings={storeBindings.length > 1} />
      }}
    </Query>
  )
}

export default React.memo(RedirectListWrapper)

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of admin-pages/react/InstitutionalPageForm.tsx from the admin-pages VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Component } from 'react'
import { FormattedMessage } from 'react-intl'
import { withRuntimeContext } from 'vtex.render-runtime'
import { Box, ToastConsumer } from 'vtex.styleguide'

import { RouteFormData } from 'pages'

import Form from './components/admin/institutional/Form'
import withContentContext, {
  ContentContextProps,
} from './components/admin/institutional/Form/withContentContext'
import { parseStoreAppId } from './components/admin/institutional/utils'

import {
  INSTITUTIONAL_ROUTES_LIST,
  NEW_ROUTE_ID,
  DATA_SOURCE,
} from './components/admin/pages/consts'
import Title from './components/admin/pages/Form/Title'
import { formatToFormData } from './components/admin/pages/Form/utils'
import { getRouteTitle } from './components/admin/pages/utils'
import {
  TargetPathContextProps,
  withTargetPath,
} from './components/admin/TargetPathContext'
import { TargetPathRenderProps } from './PagesAdminWrapper'

import withStoreSettings, {
  FormProps,
} from './components/admin/store/StoreForm/components/withStoreSettings'

interface CustomProps {
  params: {
    id: string
  }
  runtime: RenderContext
}

type Props = CustomProps &
  RenderContextProps &
  TargetPathRenderProps &
  TargetPathContextProps &
  FormProps &
  ContentContextProps

interface State {
  formData: RouteFormData
  routeId: string
}

class PageForm extends Component<Props, State> {
  private isNew: boolean

  public constructor(props: Props) {
    super(props)

    const { params, route } = props
    const routeId = decodeURIComponent(params.id)

    this.isNew = routeId === NEW_ROUTE_ID
    this.state = {
      formData: route ? formatToFormData(route) : this.defaultFormData(),
      routeId,
    }
  }

  public render() {
    const {
      store,
      runtime,
      content,
      saveRoute,
      deleteRoute,
      saveContent,
    } = this.props
    const { formData } = this.state

    return (
      <div className="h-100 min-vh-100 overflow-y-auto bg-light-silver">
        <div className="center mw8 mv8">
          <Box>
            {this.isNew ? (
              <FormattedMessage id="admin/pages.admin.pages.form.title.new">
                {text => <Title>{text}</Title>}
              </FormattedMessage>
            ) : (
              formData && <Title>{getRouteTitle(formData)}</Title>
            )}
            <ToastConsumer>
              {({ showToast, hideToast }) => (
                <Form
                  store={store}
                  initialData={formData}
                  initialContent={content}
                  culture={runtime.culture}
                  onDelete={deleteRoute}
                  onExit={this.handleExit}
                  onSave={saveRoute}
                  onSaveContent={saveContent}
                  showToast={showToast}
                  hideToast={hideToast}
                />
              )}
            </ToastConsumer>
          </Box>
        </div>
      </div>
    )
  }

  private defaultFormData = (): RouteFormData => {
    const { blockId, store, interfaceId } = this.props
    const storeAppId = parseStoreAppId(store)

    return {
      auth: false,
      blockId,
      context: `${storeAppId}/ContentPageContext`,
      declarer: null,
      domain: 'store',
      interfaceId,
      metaTagDescription: '',
      metaTagKeywords: [],
      pages: [],
      path: '',
      routeId: '',
      title: '',
      uuid: undefined,
      dataSource: DATA_SOURCE,
    }
  }

  private handleExit = () => {
    this.props.runtime.navigate({ page: INSTITUTIONAL_ROUTES_LIST, params: {} })
  }
}

export default withRuntimeContext(
  withTargetPath(
    withStoreSettings(
      withContentContext(PageForm, ({ params, runtime, store }: Props) => ({
        culture: runtime.culture,
        routeId: decodeURIComponent(params.id),
        storeAppId: parseStoreAppId(store),
      }))
    )
  )
)

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of admin-pages/react/MediaGalleryWidget.tsx from the admin-pages VTEX app.

[Assistant]
Here's the implementation:

```tsx
import MediaGalleryWidget from './components/MediaGalleryWidget/index'

export default MediaGalleryWidget

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of admin-pages/react/package.json from the admin-pages VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "license": "UNLICENSED",
  "scripts": {
    "checkTypes": "tsc --noEmit",
    "ci": "run-p lint:locales test",
    "format": "prettier -l './**/*.+(json|css|md|graphql|ts|tsx)'",
    "lint": "eslint -c .eslintrc ./ --ext ts,tsx --max-warnings=0",
    "lint:locales": "intl-equalizer",
    "test": "vtex-test-tools test"
  },
  "lint-staged": {
    "**/*.+(json|css|md|graphql)": [
      "npm run lint:locales",
      "prettier -l"
    ],
    "**/*.+(ts|tsx)": [
      "eslint -c .eslintrc",
      "npm run lint:locales",
      "prettier -l"
    ]
  },
  "intl-equalizer": {
    "referenceLocale": "en",
    "localeDirectory": "../messages/"
  },
  "dependencies": {
    "@apollo/react-testing": "^3.1.3",
    "@vtex/admin-ui": "^0.106.5",
    "axios": "^1.7.2",
    "classnames": "^2.2.6",
    "deep-object-diff": "^1.1.0",
    "draft-js": "^0.10.5",
    "draftjs-md-converter": "^1.2.0",
    "exenv": "^1.2.2",
    "json-schema-traverse": "^0.4.1",
    "keydown-from-click": "^1.1.1",
    "lodash": "^4.17.15",
    "query-string": "^6.13.8",
    "ramda": "^0.25.0",
    "react-dropzone": "^10.1.3",
    "react-jsonschema-form": "^1.0.1",
    "react-router-dom": "^5.0.0",
    "react-select": "^1.2.1",
    "react-sortable-hoc": "^1.9.1",
    "react-spring": "^8.0.18",
    "react-transition-group": "^4.2.2",
    "simple-element-resize-detector": "^1.3.0",
    "streamsaver": "^2.0.3",
    "text-encoding": "^0.7.0",
    "url-parse": "^1.4.3",
    "uuid": "^9.0.1",
    "vtex.ajv": "^6.10.4",
    "web-streams-polyfill": "^2.0.6"
  },
  "devDependencies": {
    "@types/classnames": "^2.2.6",
    "@types/draft-js": "^0.10.34",
    "@types/file-saver": "^2.0.0",
    "@types/graphql": "^14.2.3",
    "@types/intl": "^1.2.0",
    "@types/jest": "^24.0.15",
    "@types/lodash": "^4.14.136",
    "@types/node": "^11.12.0",
    "@types/prop-types": "^15.5.2",
    "@types/ramda": "types/npm-ramda#dist",
    "@types/react": "^16.8.10",
    "@types/react-datepicker": "^2.2.1",
    "@types/react-dom": "^16.8.0",
    "@types/react-helmet": "^5.0.5",
    "@types/react-jsonschema-form": "^1.0.7",
    "@types/react-router-dom": "^4.3.2",
    "@types/react-select": "1.2.1",
    "@types/react-transition-group": "^4.2.2",
    "@types/url-parse": "^1.4.3",
    "@types/uuid": "^9.0.8",
    "@vtex/intl-equalizer": "^2.3.0",
    "@vtex/test-tools": "^3.0.0",
    "apollo-cache-inmemory": "^1.5.1",
    "apollo-client": "^2.5.1",
    "apollo-client-preset": "^1.0.8",
    "babel": "^6.23.0",
    "babel-preset-env": "^1.6.1",
    "babel-preset-react-app": "^3.1.1",
    "enzyme": "^3.3.0",
    "enzyme-adapter-react-16": "^1.1.1",
    "enzyme-react-intl": "^2.0.0",
    "eslint": "^6.2.1",
    "eslint-config-vtex-react": "^5.0.1",
    "graphql": "^0.13.2",
    "graphql-tag": "^2.9.1",
    "intl": "^1.2.5",
    "lint-staged": "^9.2.3",
    "mockdate": "^2.0.4",
    "moment": "^2.22.2",
    "npm-run-all": "^4.1.5",
    "prettier": "^1.18.2",
    "react": "^16.8.1",
    "react-apollo": "^2.5.3",
    "react-dom": "^16.8.1",
    "react-intl": "3.x",
    "typescript": "3.9.7",
    "vtex.admin-cms": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.admin-cms@0.38.0/public/@types/vtex.admin-cms",
    "vtex.apps-graphql": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.apps-graphql@2.8.0/public/@types/vtex.apps-graphql",
    "vtex.file-manager": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.file-manager@0.10.1/public/_types/react",
    "vtex.file-manager-graphql": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.file-manager-graphql@0.3.0/public/@types/vtex.file-manager-graphql",
    "vtex.messages": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.messages@1.64.0/public/@types/vtex.messages",
    "vtex.native-types": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.native-types@0.7.5/public/@types/vtex.native-types",
    "vtex.pages-graphql": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.pages-graphql@2.108.3/public/@types/vtex.pages-graphql",
    "vtex.pwa-graphql": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.pwa-graphql@1.17.0/public/@types/vtex.pwa-graphql",
    "vtex.render-runtime": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.render-runtime@8.130.0/public/@types/vtex.render-runtime",
    "vtex.rewriter": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.rewriter@1.53.3/public/@types/vtex.rewriter",
    "vtex.store": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.store@2.120.0/public/@types/vtex.store",
    "vtex.styleguide": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.styleguide@9.144.0/public/@types/vtex.styleguide",
    "vtex.styles-graphql": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.styles-graphql@1.18.0/public/@types/vtex.styles-graphql",
    "vtex.tenant-graphql": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.tenant-graphql@0.1.2/public/@types/vtex.tenant-graphql"
  },
  "version": "4.59.0"
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of admin-pages/react/styles.global.css from the admin-pages VTEX app.

[Assistant]
Here's the implementation:

```css
@import '~react-select/dist/react-select.css';

.vtex-admin-pages-4-x .form-group {
  padding-top: 10px;
  padding-bottom: 10px;
}

.vtex-admin-pages-4-x .form-group.field.field-object > label {
  border-top: 2px solid #f0f2f4;
  color: #c3c4c5;
  font-weight: 700;
  margin-top: 10px;
  padding: 20px 0px 5px;
  text-transform: uppercase;
}

.vtex-admin-pages-4-x .form-group.field.field-object:first-child > label {
  border-top: none;
  margin-top: 0;
  padding-top: 0;
}

.vtex-admin-pages-4-x-accordion-item-settings .form-group .field {
  margin: 2rem 0;
}

.vtex-admin-pages-4-x .field-description {
  font-size: 12px;
  color: #979899;
  margin-top: 0px;
  font-style: italic;
}

.vtex-admin-pages-4-x .form-control {
  border: 2px solid #e1e3e5;
  height: 40px;
  width: 100%;
  font-size: 14px;
  padding-left: 12px;
  background-color: #ffffff;
}

.vtex-admin-pages-4-x .radio-inline > span > span {
  padding-left: 5px;
  padding-right: 15px;
}

.vtex-admin-pages-4-x .field-range-wrapper > input {
  width: 80%;
}

.vtex-admin-pages-4-x .field-range-wrapper {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.vtex-admin-pages-4-x .field-range-wrapper > span {
  font-size: 16px;
  font-weight: 700;
  padding-right: 3px;
  color: #368df7;
}

.vtex-admin-pages-4-x .panel-danger {
  position: fixed;
  width: 100%;
}

.vtex-admin-pages-4-x .binding-selector .vtex-dropdown label > div {
  background: #eef3f7;
  border-bottom-right-radius: 0;
  border-top-right-radius: 0;
}

.vtex-admin-pages-4-x .binding-selector .vtex-dropdown .vtex-dropdown__caption {
  color: #134cd8;
}

.vtex-admin-pages-4-x
  .binding-selector-disabled
  .vtex-dropdown
  .vtex-dropdown__caption {
  color: #979899;
}

.vtex-admin-pages-4-x
  .locale-selector-with-bindings
  .vtex-dropdown
  label
  > div {
  border-bottom-left-radius: 0;
  border-top-left-radius: 0;
}

.vtex-admin-pages-4-x
  .locale-selector-with-bindings
  .vtex-dropdown
  .vtex-dropdown__arrow {
  color: #3f3f40;
}

@media screen and (min-width: 30em) {
  .vtex-admin-pages-4-x .w-18em-ns {
    width: 18em;
  }
}

@media only screen and (min-width: 40em) {
  .vtex-admin-pages-4-x .field-range-wrapper > input {
    width: 85%;
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of admin-pages/react/PageEditor.tsx from the admin-pages VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { useEffect } from 'react'
import { useRuntime } from 'vtex.render-runtime'

import StoreIframe from './components/EditorContainer/StoreIframe'
import EditorProvider from './components/EditorProvider'
import { TemporaryAlert } from './components/TemporaryAlert'
import { useAdminLoadingContext } from './utils/AdminLoadingContext'

interface Props extends RenderContextProps {
  page: string
  params: {
    targetPath: string
  }
  query?: Record<string, string>[]
}

const PageEditor: React.FC<Props> = props => {
  const { page, params, query } = props

  const queryString =
    query === undefined || query === null
      ? ''
      : `?${Object.entries(query)
          .map(([key, value]) => `${key}=${value}`)
          .join('&')}`

  const runtime = useRuntime()

  if (page.includes('storefront')) {
    runtime.navigate({
      page: page.replace('storefront', 'site-editor'),
      params,
    })
  }

  const isSiteEditor = React.useMemo(() => page.includes('site-editor'), [page])

  const path = params?.targetPath && `${params.targetPath}${queryString ?? ''}`

  const { stopLoading } = useAdminLoadingContext()

  useEffect(() => {
    stopLoading()
  }, [stopLoading])

  return (
    <div className="h-100 overflow-y-auto bg-light-silver">
      <TemporaryAlert />
      <EditorProvider isSiteEditor={isSiteEditor}>
        <StoreIframe path={path} />
      </EditorProvider>
    </div>
  )
}

export default PageEditor

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of admin-pages/react/HighlightOverlay.tsx from the admin-pages VTEX app.

[Assistant]
Here's the implementation:

```tsx
export { default } from './components/HighlightOverlay'

export { State } from './components/HighlightOverlay/typings'

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of admin-pages/react/EmptyExtensionPoint.tsx from the admin-pages VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'

interface Props {
  children?: React.ReactNode
}

// Backwards compatibility, we can delete this file upon releasing the next render-runtime.
const EmptyExtensionPoint = ({ children }: Props) => children || null

export default EmptyExtensionPoint

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of admin-pages/react/RedirectList.tsx from the admin-pages VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { useCallback, useEffect, useState } from 'react'
import { Query, QueryResult, withApollo, WithApolloClient } from 'react-apollo'
import { defineMessages, useIntl } from 'react-intl'
import streamSaver from 'streamsaver'
import { TextEncoder } from 'text-encoding'
import { Helmet } from 'vtex.render-runtime'
import { Alert, Box, Pagination, ToastConsumer } from 'vtex.styleguide'
import * as WebStreamsPolyfill from 'web-streams-polyfill/ponyfill'

import {
  getCSVHeader,
  getCSVTemplate,
  PAGINATION_START,
  PAGINATION_STEP,
  WRAPPER_PATH,
  REDIRECTS_LIMIT,
} from './components/admin/redirects/consts'
import ImportErrorModal from './components/admin/redirects/ImportErrorModal'
import List from './components/admin/redirects/List'
import UploadModal from './components/admin/redirects/UploadModal'
import { AlertState } from './components/admin/redirects/typings'
import {
  TargetPathContextProps,
  withTargetPath,
} from './components/admin/TargetPathContext'
import Redirects from './queries/Redirects.graphql'
import RedirectWithoutBinding from './queries/RedirectWithoutBinding.graphql'

interface CustomProps {
  hasMultipleBindings: boolean
}

type Props = CustomProps & WithApolloClient<TargetPathContextProps>

interface RedirectListQueryResult {
  redirect: {
    listRedirects: {
      routes: Redirect[]
      next?: string
    }
  }
}

interface RedirectListVariables {
  limit: number
  next?: string
}

const messages = defineMessages({
  error: {
    defaultMessage: 'Something went wrong.',
    id: 'admin/pages.admin.redirects.error',
  },
  retry: {
    defaultMessage: 'Try again',
    id: 'admin/pages.admin.redirects.error.retry',
  },
  showRows: {
    defaultMessage: 'Number of rows',
    id: 'admin/pages.admin.redirects.pagination.showRows',
  },
  title: {
    defaultMessage: 'Redirect list',
    id: 'admin/pages.admin.redirects.title',
  },
})

streamSaver.WritableStream = WebStreamsPolyfill.WritableStream

const textEncoder = new TextEncoder()

const RedirectList: React.FC<Props> = ({
  client,
  setTargetPath,
  hasMultipleBindings,
}) => {
  const intl = useIntl()

  useEffect(() => {
    setTargetPath(WRAPPER_PATH)
  }, [setTargetPath])

  const [isModalOpen, setIsModalOpen] = useState(false)

  const [{ paginationFrom, paginationTo }, setPagination] = useState({
    paginationFrom: PAGINATION_START,
    paginationTo: PAGINATION_START + PAGINATION_STEP,
  })

  const [alertState, setAlert] = useState<AlertState | null>(null)

  const [isImportErrorModalOpen, setIsImportErrorModalOpen] = useState(false)

  const [redirectList, setRedirectList] = useState<Redirect[]>([])
  const [filtered, setFiltered] = useState<boolean>(false)

  const openModal = useCallback(() => {
    setIsModalOpen(true)
  }, [setIsModalOpen])

  const closeModal = useCallback(() => {
    setIsModalOpen(false)
  }, [setIsModalOpen])

  const resetAlert = useCallback(() => {
    setAlert(null)
  }, [setAlert])

  const handleOpenErrorModal = useCallback(() => {
    setIsImportErrorModalOpen(true)
  }, [setIsImportErrorModalOpen])

  const handleCloseErrorModal = useCallback(() => {
    setIsImportErrorModalOpen(false)
  }, [setIsImportErrorModalOpen])

  const handleDownloadTemplate = () => {
    const fileStream = streamSaver.createWriteStream('redirects_template.csv')
    const writer = fileStream.getWriter()
    writer.write(textEncoder.encode(getCSVTemplate(hasMultipleBindings)))
    writer.close()
  }

  const handleDownload = useCallback(async () => {
    const fileStream = streamSaver.createWriteStream('redirects.csv')
    const writer = fileStream.getWriter()
    let next: string | undefined

    writer.write(textEncoder.encode(getCSVHeader(hasMultipleBindings) + '\n'))
    do {
      const response = await client.query<
        RedirectListQueryResult,
        RedirectListVariables
      >({
        query: Redirects,
        variables: {
          limit: REDIRECTS_LIMIT,
          next,
        },
      })
      const redirects = response.data.redirect.listRedirects.routes
      next = response.data.redirect.listRedirects.next
      redirects.forEach(({ endDate, from, to, type, binding }) => {
        const bindingString = hasMultipleBindings ? `${binding || ''};` : ''
        writer.write(
          textEncoder.encode(
            `${from};${to};${type};${bindingString}${endDate ?? ''}\n`
          )
        )
      })
    } while (next !== null)
    writer.close()
  }, [client, hasMultipleBindings])

  const getNextPageNavigationHandler = (
    dataLength: number,
    fetchMore: QueryResult<
      RedirectListQueryResult,
      RedirectListVariables
    >['fetchMore'],
    nextToken?: string
  ) => async () => {
    if (!nextToken && paginationFrom >= dataLength) {
      return
    }
    const maybeNextPaginationTo = paginationTo + PAGINATION_STEP

    if (maybeNextPaginationTo > dataLength && nextToken) {
      await fetchMore({
        updateQuery: (prevData, { fetchMoreResult }) => {
          if (!fetchMoreResult) {
            return prevData
          }
          prevData.redirect.listRedirects.routes = prevData.redirect.listRedirects.routes.concat(
            fetchMoreResult.redirect.listRedirects.routes
          )
          prevData.redirect.listRedirects.next =
            fetchMoreResult.redirect.listRedirects.next
          return prevData
        },
        variables: {
          limit: REDIRECTS_LIMIT,
          next: nextToken,
        },
      })
    }

    const nextPaginationTo =
      maybeNextPaginationTo > dataLength ? dataLength : maybeNextPaginationTo
    setPagination(prevState => ({
      paginationFrom:
        prevState.paginationTo >= nextPaginationTo
          ? prevState.paginationFrom
          : prevState.paginationTo,
      paginationTo: nextPaginationTo,
    }))
  }
  const handlePrevPageNavigation = useCallback(() => {
    setPagination(prevState => ({
      paginationFrom:
        prevState.paginationFrom - PAGINATION_STEP < 0
          ? 0
          : prevState.paginationFrom - PAGINATION_STEP,
      paginationTo: prevState.paginationFrom,
    }))
  }, [setPagination])

  return (
    <>
      <Helmet>
        <title>{intl.formatMessage(messages.title)}</title>
      </Helmet>
      <Query<RedirectListQueryResult, RedirectListVariables>
        notifyOnNetworkStatusChange
        query={Redirects}
        variables={{
          limit: REDIRECTS_LIMIT,
        }}
      >
        {({ data, fetchMore, loading, refetch, error }) => {
          const redirects = data?.redirect?.listRedirects.routes ?? []
          const hasRedirects = redirects.length > 0

          const handleInputSearchChange = async (
            e: React.ChangeEvent<HTMLInputElement>,
            innerData: RedirectListQueryResult | undefined = undefined
          ) => {
            e.persist()

            const term = e.target.value.toLowerCase()
            const innerRedirects = innerData?.redirect?.listRedirects.routes
            const filteredRedirects = (innerRedirects?.length
              ? innerRedirects
              : redirects
            ).filter(item => item.from.toLowerCase().includes(term))

            if (paginationFrom > PAGINATION_START) {
              setPagination({
                paginationFrom: PAGINATION_START,
                paginationTo: PAGINATION_START + PAGINATION_STEP,
              })
            }

            const searchExactMatchRedirect = async (term: string) => {
              if (!term) return []
              const { data } = await client.query({
                query: RedirectWithoutBinding,
                variables: {
                  path: term,
                },
              })

              const { get: redirectFound } = data?.redirect ?? {}
              return redirectFound ? [redirectFound] : []
            }

            const exactMatchRedirect = await searchExactMatchRedirect(term)

            if (exactMatchRedirect.length > 0) {
              setRedirectList(exactMatchRedirect)
            } else {
              setRedirectList(filteredRedirects)
            }

            if (term.length) {
              setFiltered(true)
            } else {
              setFiltered(false)
            }
          }

          if (error) {
            return (
              <>
                {intl.formatMessage(messages.error)}
                <button
                  className="bg-transparent bn c-action-primary pointer"
                  onClick={() => {
                    refetch({ limit: REDIRECTS_LIMIT })
                  }}
                >
                  {intl.formatMessage(messages.retry)}
                </button>
              </>
            )
          }
          const next = data?.redirect?.listRedirects.next
          if (next && redirects.length < PAGINATION_STEP) {
            refetch({ limit: REDIRECTS_LIMIT, next })
          }

          return (
            <ToastConsumer>
              {({ showToast }) => (
                <>
                  {alertState && (
                    <div className="mb4">
                      <Alert
                        type={alertState.type}
                        onClose={resetAlert}
                        action={
                          alertState.meta && alertState.action
                            ? {
                                ...alertState.action,
                                onClick: handleOpenErrorModal,
                              }
                            : undefined
                        }
                      >
                        {alertState.message}
                      </Alert>
                    </div>
                  )}
                  {isImportErrorModalOpen && alertState?.meta && (
                    <ImportErrorModal
                      isSave={alertState.meta.isSave}
                      isOpen={isImportErrorModalOpen}
                      mutation={alertState.meta.mutation}
                      onClose={handleCloseErrorModal}
                      redirects={alertState.meta.failedRedirects}
                      setAlert={setAlert}
                      hasMultipleBindings={hasMultipleBindings}
                    />
                  )}
                  <Box>
                    <List
                      loading={loading}
                      from={paginationFrom}
                      items={(filtered ? redirectList : redirects).slice(
                        paginationFrom,
                        paginationTo
                      )}
                      refetch={() => {
                        refetch({
                          limit: REDIRECTS_LIMIT,
                        })
                      }}
                      to={paginationTo}
                      showToast={showToast}
                      openModal={openModal}
                      onHandleDownload={handleDownload}
                      onHandleInputSearchChange={handleInputSearchChange}
                    />
                    {redirects.length > 0 && (
                      <Pagination
                        currentItemFrom={paginationFrom + 1}
                        currentItemTo={paginationTo}
                        onNextClick={getNextPageNavigationHandler(
                          redirects.length,
                          fetchMore,
                          next
                        )}
                        textOf=""
                        onPrevClick={handlePrevPageNavigation}
                        textShowRows={intl.formatMessage(messages.showRows)}
                      />
                    )}
                    <UploadModal
                      isOpen={isModalOpen}
                      hasRedirects={hasRedirects}
                      onClose={closeModal}
                      onDownloadTemplate={handleDownloadTemplate}
                      refetchRedirects={refetch}
                      setAlert={setAlert}
                      hasMultipleBindings={hasMultipleBindings}
                    />
                  </Box>
                </>
              )}
            </ToastConsumer>
          )
        }}
      </Query>
    </>
  )
}

export default withApollo(withTargetPath(RedirectList))

```