Naano WP / docs
Download 2.3.9 Télécharger 2.3.9
Documentation · 2.3.9

Build complete WordPress sites, section by section, with the LLM of your choice.

Créez des sites WordPress complets, section par section, avec le LLM de votre choix.

Naano WP is an AI-powered visual builder that lives entirely inside your WordPress admin. You bring your own API key. No external backend, no subscription, no data leaves your server other than the prompt itself.

Naano WP est un constructeur visuel propulsé par l'IA qui vit entièrement dans votre administration WordPress. Vous apportez votre propre clé API. Pas de backend externe, pas d'abonnement, aucune donnée ne quitte votre serveur hormis le prompt lui-même.

Most AI builders send the whole page to the model on every change. Naano WP flips that: only the section you're editing travels as full HTML. Every other section is compressed to an 8-character hash placeholder. That single decision shapes the rest of the product — faster iteration, cheaper tokens, calmer reasoning, more focused output.

La plupart des constructeurs IA envoient la page entière au modèle à chaque modification. Naano WP inverse cette logique : seule la section en cours d'édition transite en HTML complet. Toutes les autres sections sont compressées en un simple hash de 8 caractères. Ce choix architectural façonne tout le reste du produit — itérations plus rapides, tokens moins coûteux, raisonnement plus ciblé, résultats plus précis.

This guide walks through every feature: installing the plugin, configuring a provider, generating a page, editing sections individually, swapping elements via the new ♻ recycle button, publishing, translating, and extending. Each topic stands alone — jump straight to what you need from the left.

Ce guide couvre chaque fonctionnalité : installation du plugin, configuration d'un fournisseur, génération d'une page, édition section par section, remplacement d'éléments via le nouveau bouton ♻, publication, traduction et extension. Chaque sujet est autonome — naviguez directement vers ce dont vous avez besoin depuis la barre gauche.

i

What's new in 2.3.4

Nouveautés de la version 2.3.4

The element editor gains a JS tab — attach a click handler to any button straight from the panel, no theme code required. Global CSS now also applies the moment you open the editor instead of after the first interaction, and the ♻ recycle button (2.3.1) still lets you swap any element for a fresh Text or Image widget.

L'éditeur d'élément gagne un onglet JS — attachez un gestionnaire de clic à n'importe quel bouton directement depuis le panneau, sans code de thème. Le CSS global s'applique désormais dès l'ouverture de l'éditeur au lieu d'attendre la première interaction, et le bouton ♻ recycle (2.3.1) permet toujours de remplacer un élément par un widget Texte ou Image.

i

What's new in 2.3.9

Nouveautés de la version 2.3.9

Fixed button text/icon alignment in the admin pages list by removing dashicons from "Create New Page", "Site Configuration", and "Build Your First Page" buttons. Icons were causing misalignment with the text.

Correction de l'alignement du texte/icône des boutons dans la liste des pages admin en supprimant les dashicons des boutons "Créer une nouvelle page", "Configuration du site" et "Construire votre première page". Les icônes causaient un mauvais alignement avec le texte.

Getting started

Requirements #

Prérequis #

Naano WP targets a clean, modern PHP stack. If your host runs current WordPress, it runs Naano WP.

Naano WP cible une stack PHP moderne et propre. Si votre hébergeur fait tourner WordPress à jour, il peut faire tourner Naano WP.

Requirement Minimum Prérequis Minimum
WordPress 6.0 or newer
PHP 8.1 or newer
PHP extensions curl, json, gd, dom, mbstring
Outbound network HTTPS port 443 to your chosen LLM provider Réseau sortant HTTPS port 443 vers votre fournisseur LLM
Browser Any current Chromium, Firefox, or Safari Navigateur Chromium, Firefox ou Safari récent

The plugin makes every LLM call from PHP through cURL. There is no Node.js, no webpack, no build step. If you can install a WordPress plugin, you can install Naano WP.

Le plugin effectue chaque appel LLM depuis PHP via cURL. Pas de Node.js, pas de webpack, pas d'étape de build. Si vous savez installer une extension WordPress, vous savez installer Naano WP.

Getting started

Installation #

Installation #

Two paths: upload the zip through the WordPress admin, or drop the folder into /wp-content/plugins/ via FTP.

Deux options : téléverser le zip depuis l'administration WordPress, ou déposer le dossier dans /wp-content/plugins/ via FTP.

  1. Download the latest release

    Grab the naano-ai-website-builder.zip from the project's GitHub releases. Click the Download 2.3.9 button in the top-right of this page.

  2. Upload to WordPress

    In the admin sidebar, go to Plugins → Add New Plugin → Upload Plugin. Pick the zip you just downloaded and click Install Now, then Activate.

  3. Configure your provider

    A new menu appears in the sidebar: Naano AI Builder. Open Settings, pick a provider (Claude, Gemini, OpenAI, Kimi, or DeepSeek), paste your API key, and click Test connection to confirm the credentials.

  4. You're ready

    That's it — no additional server configuration required. Naano WP works out of the box on any standard WordPress host, including shared hosting. Go to Naano AI Builder → AI Pages and create your first page.

  1. Télécharger la dernière version

    Récupérez le fichier naano-ai-website-builder.zip depuis les releases GitHub du projet. Cliquez sur le Download 2.3.9 en haut à droite de cette page.

  2. Téléverser sur WordPress

    Dans la barre latérale de l'administration, allez dans Extensions → Ajouter une extension → Téléverser une extension. Sélectionnez le zip que vous venez de télécharger, cliquez sur Installer maintenant, puis sur Activer.

  3. Configurer votre fournisseur

    Un nouveau menu apparaît dans la barre latérale : Naano AI Builder. Ouvrez Réglages, choisissez un fournisseur (Claude, Gemini, OpenAI, Kimi ou DeepSeek), collez votre clé API et cliquez sur Tester la connexion pour valider les identifiants.

  4. C'est tout

    Aucune configuration serveur supplémentaire n'est nécessaire. Naano WP fonctionne immédiatement sur tout hébergement WordPress standard, y compris les hébergements mutualisés. Rendez-vous dans Naano AI Builder → AI Pages et créez votre première page.

!

Updating from a previous version

Mise à jour depuis une version précédente

WordPress caches plugin assets with the plugin's version string. After upgrading, the browser may still serve the old builder.js. Deactivate the old version, install the new zip, then hard-reload the builder page (Cmd/Ctrl + Shift + R).

WordPress met en cache les assets du plugin avec son numéro de version. Après la mise à jour, le navigateur peut continuer à servir l'ancien builder.js. Désactivez l'ancienne version, installez le nouveau zip, puis rechargez la page du builder en force (Cmd/Ctrl + Shift + R).

Quickstart Démarrage rapide

Your first page #

Votre première page #

From settings to a published page in under ten minutes.

Des réglages à une page publiée en moins de dix minutes.

  1. Add design variables

    In Settings → Custom design variables, define brand-wide values: primary_color, brand_name, font_family, tone, industry, target_audience. These are injected into every prompt for consistent output across all sections.

  2. Create a new page with AI

    Go to Naano AI Builder → AI Pages and click Create New Page with AI. Enter a page name and a short description of what the site is.

  3. Pick sections

    Check the sections you want: Header, Hero, About, Services, Testimonials, FAQ, Contact, Footer — or your own custom set. You can also import header and footer from an existing Naano WP page.

  4. Generate

    Click Generate full website. The plugin generates one section per tick, entirely automatically. The live preview iframe updates section by section as they land.

  5. Refine

    Click any element in the live preview to open the floating Element Editor. Type directly to change text. Tweak Style, Spacing, Classes, Link, Custom CSS. Or pick a whole section in the left drawer and refine it with a natural-language instruction.

  6. Publish

    Click Save changes to persist your manual edits as a draft. When you're ready, click Publish to assemble the final HTML and write it to a real WordPress page — served as raw HTML, with no theme wrapping.

  1. Ajouter des variables de design

    Dans Réglages → Variables de design personnalisées, définissez des valeurs globales à la marque : primary_color, brand_name, font_family, tone, industry, target_audience. Ces valeurs sont injectées dans chaque prompt pour garantir une cohérence sur toutes les sections.

  2. Créer une nouvelle page avec l'IA

    Allez dans Naano AI Builder → AI Pages et cliquez sur Créer une nouvelle page avec l'IA. Saisissez un nom de page et une courte description du site.

  3. Choisir les sections

    Cochez les sections souhaitées : Header, Hero, About, Services, Testimonials, FAQ, Contact, Footer — ou votre propre sélection personnalisée. Vous pouvez aussi importer le header et le footer d'une page Naano WP existante.

  4. Générer

    Cliquez sur Générer le site complet. Le plugin génère une section à chaque tick, de manière entièrement automatique. L'aperçu en direct se met à jour section par section au fur et à mesure.

  5. Affiner

    Cliquez sur n'importe quel élément dans l'aperçu pour ouvrir l'éditeur d'élément flottant. Tapez directement pour modifier le texte. Ajustez le Style, l'Espacement, les Classes, le Lien, le CSS personnalisé. Ou sélectionnez une section entière dans le panneau gauche et affinez-la avec une instruction en langage naturel.

  6. Publier

    Cliquez sur Enregistrer les modifications pour sauvegarder vos éditions manuelles en brouillon. Quand vous êtes prêt, cliquez sur Publier pour assembler le HTML final et l'écrire dans une vraie page WordPress — servie en HTML brut, sans encapsulation par le thème.

Concept

The section-by-section model #

Le modèle section par section #

A single architectural decision shapes the entire product. Here's what changes when you stop sending whole pages to the model.

Une seule décision architecturale façonne tout le produit. Voici ce qui change quand on arrête d'envoyer des pages entières au modèle.

Conventional AI website builders treat the page as one atomic unit. Each change retypes the entire page in the prompt, the entire page in the response. Naano WP works the other way around. The page is a list of sections. Only one section is in-context at any time.

Les constructeurs de sites IA classiques traitent la page comme une unité atomique. Chaque modification retranscrit la page entière dans le prompt, et la page entière dans la réponse. Naano WP fait l'inverse : la page est une liste de sections, et une seule section est en contexte à la fois.

What the model actually sees

Ce que le modèle voit réellement

When you ask Naano WP to refine the Hero, the prompt contains:

Quand vous demandez à Naano WP d'affiner le Hero, le prompt contient :

  • The full HTML of the Hero (what you're editing)
  • An ordered list of hash placeholders for every other section — eight-character fingerprints that preserve position without spending tokens on content
  • Your instruction
  • The last three user/assistant exchanges (for continuity)
  • Design variables, references, and asset citations
  • Le HTML complet du Hero (ce que vous éditez)
  • Une liste ordonnée de hash placeholders pour toutes les autres sections — des empreintes de 8 caractères qui préservent la position sans dépenser de tokens sur le contenu
  • Votre instruction
  • Les trois derniers échanges utilisateur/assistant (pour la continuité)
  • Les variables de design, références et citations d'assets

The model returns just the new Hero. Everything else is untouched on the server side.

Le modèle retourne uniquement le nouveau Hero. Tout le reste est inchangé côté serveur.

The numbers

Les chiffres

i

70–90% tokens saved

70–90 % de tokens économisés

Section placeholders compress every untouched section to ~8 characters. Cumulative savings across an editing session are dramatic.

Les placeholders de sections compriment chaque section non modifiée à ~8 caractères. Les économies cumulées sur une session d'édition sont considérables.

ii

3 exchanges of context

3 échanges de contexte

The conversation history is trimmed to the last three round-trips. Old context is pruned automatically; cost stays bounded.

L'historique de conversation est limité aux trois derniers allers-retours. L'ancien contexte est élagué automatiquement ; le coût reste maîtrisé.

iii

1 LLM call per tick

1 appel LLM par tick

The WP-Cron runner generates one section at a time, never running long enough to trip a shared-host execution ceiling.

Le runner WP-Cron génère une section à la fois, sans jamais tourner assez longtemps pour déclencher les limites d'exécution d'un hébergement mutualisé.

iv

Skip-on-fail

Passe-en-cas-d'échec

If a section's worker is killed, the runner persists what it had, advances, continues. No single section can take down a whole page.

Si le worker d'une section est interrompu, le runner persiste ce qu'il avait, avance et continue. Aucune section ne peut faire échouer toute une page.

The section is not a performance optimisation. It's a unit of attention — yours, and the model's.
La section n'est pas une optimisation de performance. C'est une unité d'attention — la vôtre, et celle du modèle.
Concept

The WP-Cron runner #

Le runner WP-Cron #

A small state machine that turns a long generation into a chain of short, recoverable ticks.

Une petite machine à états qui découpe une génération longue en une chaîne de ticks courts et récupérables.

Shared hosts kill long-running PHP processes. LSAPI_MAX_PROCESS_TIME caps execution. max_execution_time caps execution. Memory limits cap execution. A naive site generator that issues twelve sequential LLM calls in one request will run for one or two minutes and die before it finishes.

Les hébergements mutualisés interrompent les processus PHP trop longs. LSAPI_MAX_PROCESS_TIME limite l'exécution. max_execution_time aussi. Les limites mémoire aussi. Un générateur naïf qui émet douze appels LLM séquentiels dans une seule requête tournera une à deux minutes avant de mourir avant la fin.

Naano WP sidesteps the problem entirely. When you click Generate full website, the AJAX handler:

Naano WP contourne entièrement ce problème. Quand vous cliquez sur Générer le site complet, le handler AJAX :

  1. Creates a job in a transient (a small object: cursor, sections, log, status).
  2. Schedules the first WP-Cron tick.
  3. Returns a job_id immediately.
  1. Crée un job dans un transient (un petit objet : curseur, sections, journal, statut).
  2. Programme le premier tick WP-Cron.
  3. Retourne immédiatement un job_id.

Each tick does one thing: call the LLM for one section, sanitise the response, store it, advance the cursor, schedule the next tick. The browser polls naano_poll_job every couple of seconds for progress. No server-side configuration is required — WP-Cron fires automatically on incoming page requests, which is standard WordPress behaviour.

Chaque tick fait une seule chose : appeler le LLM pour une section, assainir la réponse, la stocker, avancer le curseur, programmer le tick suivant. Le navigateur interroge naano_poll_job toutes les deux secondes pour suivre la progression. Aucune configuration serveur n'est requise — WP-Cron se déclenche automatiquement sur les requêtes entrantes, ce qui est le comportement standard de WordPress.

If the worker is killed mid-tick — host timeout, memory exceeded, anything — the next tick reads the persisted state and continues from where the cursor stopped. The section that failed gets recorded in _naano_failed_sections with a reason. You see it as an entry in the Failed sections drawer with a one-click Retry. A site with twelve sections will never die on one bad section.

Si le worker est interrompu en plein tick — timeout de l'hébergeur, mémoire dépassée, autre — le tick suivant relit l'état persisté et reprend là où le curseur s'était arrêté. La section échouée est enregistrée dans _naano_failed_sections avec une raison. Elle apparaît dans le panneau Sections échouées avec un bouton Réessayer en un clic. Un site de douze sections ne peut jamais échouer à cause d'une seule mauvaise section.

Concept

Token optimisation #

Optimisation des tokens #

A list of small techniques compounded into substantial savings.

Une série de petites techniques qui s'accumulent pour des économies substantielles.

Strategy Typical saving
Stratégie Économie typique
Section placeholders (hash compression) 70–90% on section updates
Placeholders de section (compression hash) 70–90 % sur les mises à jour
HTML minification 15–25%
Minification HTML 15–25 %
Inline CSS minification 10–20%
Minification CSS inline 10–20 %
Conversation trimming (last 3 exchanges) Prevents runaway cost growth
Élagage de conversation (3 derniers échanges) Empêche la dérive des coûts
Image resize to 1024 px JPEG 75% 50–80% on vision tokens
Redimensionnement image 1024 px JPEG 75 % 50–80 % sur les tokens vision
Single-section responses 60–80% on response size
Réponses mono-section 60–80 % sur la taille des réponses

These add up. A refinement of a Hero section on a 12-section page typically costs 1,000–3,000 tokens on the request side instead of 15,000–30,000. With Gemini Flash on the free tier, you can build and refine an entire site without paying a cent. With Claude Sonnet, expect a few cents per page.

Ces techniques s'accumulent. L'affinage d'une section Hero sur une page de 12 sections coûte généralement 1 000–3 000 tokens en entrée au lieu de 15 000–30 000. Avec Gemini Flash en offre gratuite, vous pouvez construire et affiner un site entier sans débourser un centime. Avec Claude Sonnet, comptez quelques centimes par page.

Building a page

Generating a page #

Générer une page #

What the model needs from you, and what shows up in its prompt without you noticing.

Ce que le modèle attend de vous, et ce qui apparaît dans son prompt sans que vous le voyiez.

Description

Description

Two or three sentences. What is the site? Who is it for? What's the tone? The description is reused on every subsequent section generation, so it acts as the page's "north star".

Deux ou trois phrases. Quel est le site ? À qui est-il destiné ? Quel est le ton ? La description est réutilisée à chaque génération de section — elle sert d'« étoile polaire » à la page.

Sections

Sections

A checklist of section types. You can pick the standard set (Header, Hero, About, Services, Testimonials, FAQ, Contact, Footer) or add custom ones. The runner generates them in the order you've listed.

Une liste de types de sections à cocher. Vous pouvez choisir l'ensemble standard (Header, Hero, About, Services, Testimonials, FAQ, Contact, Footer) ou en ajouter des personnalisées. Le runner les génère dans l'ordre que vous avez défini.

Imported sections

Sections importées

If you already have a Naano WP page with a header you like, you can import it directly. The HTML is copied server-side from the source page's _naano_sections meta. It never travels through the browser — no payload bloat, no risk of HTML mangling in transit.

Si vous avez déjà une page Naano WP avec un header qui vous convient, vous pouvez l'importer directement. Le HTML est copié côté serveur depuis la meta _naano_sections de la page source. Il ne transite jamais par le navigateur — aucun gonflement de payload, aucun risque de corruption HTML en transit.

Design variables (injected automatically)

Variables de design (injectées automatiquement)

Whatever you set in Settings is injected into every prompt as a structured "Design system" block.

Tout ce que vous définissez dans les Réglages est injecté dans chaque prompt sous forme d'un bloc structuré « Système de design ».

Variable Example Used for
Variable Exemple Utilisée pour
primary_color #2776ea Buttons, headings, accents Boutons, titres, accents
secondary_color #10B981 Highlights, secondary elements Mises en valeur, éléments secondaires
brand_name Acme Corp Brand name throughout Nom de marque partout
font_family Inter, sans-serif Typography Typographie
tone modern and minimal Overall aesthetic direction Direction esthétique globale
industry SaaS / Technology Industry-appropriate copy and imagery Textes et visuels adaptés au secteur
target_audience small teams, startups Tailored messaging Messagerie ciblée

You can add any custom key as well. The model receives the full list every time.

Vous pouvez aussi ajouter n'importe quelle clé personnalisée. Le modèle reçoit la liste complète à chaque fois.

Building a page

The element editor #

L'éditeur d'élément #

Clicking is the only mode. No toggle. No state to remember.

Cliquer est le seul mode. Pas de bascule. Rien à mémoriser.

Inspect mode is permanently on. Click any element in the live preview — heading, paragraph, button, image, the section root itself — and a floating panel slides in from the top-right of the canvas. The clicked element gets a solid orange outline and becomes contenteditable: you can type directly to change the text.

Le mode inspection est toujours actif. Cliquez sur n'importe quel élément dans l'aperçu en direct — titre, paragraphe, bouton, image, la racine de section elle-même — et un panneau flottant apparaît en haut à droite du canevas. L'élément cliqué reçoit un contour orange et devient contenteditable : vous pouvez taper directement pour modifier le texte.

Six tabs, six intents

Six onglets, six intentions

The Link, Image, and JS tabs are contextual — they only appear when the selected element matches (an <a>, an <img>, or a button respectively), so the panel never shows an irrelevant tab.

Les onglets Lien, Image et JS sont contextuels — ils n'apparaissent que lorsque l'élément sélectionné correspond (un <a>, un <img> ou un bouton respectivement), pour que le panneau n'affiche jamais d'onglet hors sujet.

a
Style Typography (color, size, weight, alignment), background (color, image, size), border, border-radius. Live-applied in the iframe on change — no separate Apply for visual tweaks. Typographie (couleur, taille, graisse, alignement), arrière-plan (couleur, image, taille), bordure, border-radius. Appliqué en direct dans l'iframe au changement — pas besoin d'un bouton Appliquer séparé.
b
Spacing Espacement Width, height, max-width, and an independent input for every side of padding and margin (T/R/B/L). No shorthand that silently overwrites the others. Largeur, hauteur, max-width, et une entrée indépendante pour chaque côté du padding et de la marge (H/D/B/G). Pas de raccourci qui écrase silencieusement les autres.
c
Classes Space-separated CSS class names. The AI-generated classes are preserved — the iframe merges your input with the model's existing classes instead of overwriting them. Noms de classes CSS séparés par des espaces. Les classes générées par l'IA sont préservées — l'iframe fusionne votre saisie avec les classes existantes du modèle au lieu de les écraser.
d
Link (visible only on <a> elements) Lien (visible uniquement sur les éléments <a>) Edit href, target, rel. The anchor dropdown lists every data-section id on the page so you can wire internal anchors (#hero, #contact) without typing. Modifiez href, target, rel. Le menu déroulant d'ancres liste tous les identifiants data-section de la page pour câbler des ancres internes (#hero, #contact) sans taper.
e
Custom CSS CSS personnalisé Freeform CSS scoped to the element via [data-naano-el="…"]. Useful for hover states, transitions, animations — anything the structured tabs don't cover. CSS libre scopé à l'élément via [data-naano-el="…"]. Utile pour les états hover, transitions, animations — tout ce que les onglets structurés ne couvrent pas.
f
JS (buttons only) New 2.3.2 JS (boutons uniquement) Nouveau 2.3.2 Attach a click handler to a button without touching theme files. The code runs on the published page only when the button is clicked, with this bound to the button and event available. See the Button JS section for the full model. Attachez un gestionnaire de clic à un bouton sans toucher aux fichiers du thème. Le code s'exécute uniquement sur la page publiée au clic sur le bouton, avec this lié au bouton et event disponible. Voir la section JS des boutons pour le modèle complet.

Footer actions

Actions du pied de panneau

Below the tabs sit four actions: Delete the element (cannot delete a section root), Edit section with AI (closes the panel, opens the AI editor for the parent section), Done (deselect without applying), Apply (push everything to the iframe).

Sous les onglets se trouvent quatre actions : Supprimer l'élément (impossible sur la racine d'une section), Modifier la section avec l'IA (ferme le panneau, ouvre l'éditeur IA de la section parente), Terminer (désélectionner sans appliquer), Appliquer (pousser tout vers l'iframe).

i

Save changes vs Publish

Enregistrer vs Publier

The toolbar separates the two: Save changes (the orange button, visible only when you have unsaved edits) writes manual edits and global CSS to a draft store. Publish assembles the final HTML server-side and writes it to the live WordPress page. They are intentionally distinct actions.

La barre d'outils distingue les deux : Enregistrer les modifications (le bouton orange, visible uniquement quand vous avez des éditions non sauvegardées) écrit les modifications manuelles et le CSS global dans le brouillon. Publier assemble le HTML final côté serveur et l'écrit dans la page WordPress en ligne. Ce sont intentionnellement deux actions distinctes.

Building a page

Button JS New 2.3.2#

JS des boutons Nouveau 2.3.2#

Attach a click handler to a button straight from the element editor — no theme files, no enqueue, no build step.

Attachez un gestionnaire de clic à un bouton directement depuis l'éditeur d'élément — sans fichier de thème, sans enqueue, sans étape de build.

Select a button in the live preview and a JS tab appears in the floating panel. The tab is shown only for button-like elements: a <button>, an <input type="button|submit|reset">, anything with role="button", or an <a> whose class contains btn, button, or cta. Type raw JavaScript into the textarea and click Apply.

Sélectionnez un bouton dans l'aperçu en direct et un onglet JS apparaît dans le panneau flottant. L'onglet n'est affiché que pour les éléments de type bouton : un <button>, un <input type="button|submit|reset">, tout élément avec role="button", ou un <a> dont la classe contient btn, button ou cta. Tapez du JavaScript brut dans la zone de texte et cliquez sur Appliquer.

Execution model

Modèle d'exécution

Your code runs on the published page only, as the button's click handler. Inside it, this is the button element and event is the click event. It never runs inside the editor preview — clicks there are reserved for selecting elements, so a builder flag short-circuits the handler.

Votre code s'exécute uniquement sur la page publiée, comme gestionnaire click du bouton. À l'intérieur, this est l'élément bouton et event est l'événement de clic. Il ne s'exécute jamais dans l'aperçu de l'éditeur — les clics y servent à sélectionner les éléments, donc un drapeau du builder court-circuite le gestionnaire.

js// 'this' is the clicked button, 'event' is the click event
event.preventDefault();      // needed when the button submits a form
this.textContent = 'Merci !';
this.disabled = true;

How it persists

Comment c'est persisté

The model mirrors Custom CSS exactly. Your code is stored verbatim on the button as a data-naano-cust-js attribute — the single source of truth, atomic with the element and automatically HTML-escaped on serialization. A generic <script data-naano-cust-scripts> block is regenerated at the end of the section; it reads each button's code at click time, so nothing is inlined into the script body (a stray </script> can never break out). Both the attribute and the script survive the server-side sanitizer, which keeps inline scripts and data-* attributes.

Le modèle reproduit exactement celui du CSS personnalisé. Votre code est stocké tel quel sur le bouton dans un attribut data-naano-cust-js — la source de vérité unique, atomique avec l'élément et automatiquement échappée en HTML à la sérialisation. Un bloc générique <script data-naano-cust-scripts> est régénéré en fin de section ; il lit le code de chaque bouton au moment du clic, donc rien n'est inliné dans le corps du script (un </script> égaré ne peut jamais s'en échapper). L'attribut comme le script survivent au sanitizer côté serveur, qui conserve les scripts inline et les attributs data-*.

i

Mistakes don't navigate you away

Une erreur ne vous redirige pas

If your code throws (a syntax or runtime error), the binder calls event.preventDefault() and logs to the console — so a broken handler on a type="submit" button never lets the form navigate to a blank or default page. The editor also validates the syntax when you click Apply (same new Function compile the live page uses) and shows the exact error in a toast, while still saving so you don't lose your work.

Si votre code lève une erreur (de syntaxe ou d'exécution), le binder appelle event.preventDefault() et journalise dans la console — un gestionnaire cassé sur un bouton type="submit" ne laisse donc jamais le formulaire naviguer vers une page vide ou par défaut. L'éditeur valide aussi la syntaxe au clic sur Appliquer (la même compilation new Function que la page en ligne) et affiche l'erreur exacte dans une notification, tout en enregistrant pour ne pas perdre votre travail.

!

It runs real JavaScript on your live page

Cela exécute du vrai JavaScript sur votre page en ligne

Whatever you type executes in the visitor's browser when the button is clicked. Treat it like any other code you ship: only editors you trust should have builder access. For a button that submits a form, call event.preventDefault() first (or bind a submit handler that does) so the page doesn't reload. If your handler calls a REST endpoint, make sure the route is actually registered with register_rest_route.

Tout ce que vous tapez s'exécute dans le navigateur du visiteur au clic sur le bouton. Traitez-le comme n'importe quel code que vous déployez : seuls des éditeurs de confiance devraient avoir accès au builder. Pour un bouton qui soumet un formulaire, appelez d'abord event.preventDefault() (ou liez un gestionnaire submit qui le fait) afin que la page ne se recharge pas. Si votre gestionnaire appelle un point d'accès REST, assurez-vous que la route est bien enregistrée via register_rest_route.

Building a page

The recycle button New 2.3.1#

Le bouton ♻ Nouveau 2.3.1#

A second hover affordance — alongside the section "+", smaller, scoped to a single element. One click and you swap the element for a fresh widget.

Une deuxième affordance au survol — à côté du "+" de section, plus petite, limitée à un seul élément. Un clic et vous remplacez l'élément par un widget tout neuf.

Hovered heading ♻ When the cursor is over an element, a small amber ♻ button appears at its top-right corner. Click it to open the widget picker. Quand le curseur survole un élément, un petit bouton ♻ ambré apparaît dans son coin supérieur droit. Cliquez dessus pour ouvrir le sélecteur de widget.

What happens on click

Ce qui se passe au clic

A modal opens with two cards: Text and Image. Pick one and the element is replaced in place — same position, same parent, AI-generated classes preserved so the new widget sits visually inside the section's existing layout.

Une modale s'ouvre avec deux cartes : Texte et Image. Choisissez-en une et l'élément est remplacé sur place — même position, même parent, classes générées par l'IA préservées pour que le nouveau widget s'intègre visuellement dans la mise en page existante de la section.

The text widget

Le widget Texte

Replaces the element with a <p> containing the placeholder string "Texte à éditer…". The paragraph inherits the original element's classes (minus inspect-mode helpers) and is immediately editable — click it to start typing right away.

Remplace l'élément par un <p> contenant la chaîne placeholder "Texte à éditer…". Le paragraphe hérite des classes de l'élément original (sans les helpers du mode inspection) et est immédiatement éditable — cliquez dessus pour commencer à taper.

The image widget

Le widget Image

Closes the modal and opens the WordPress media library directly. Pick an image; on select the element is replaced with an <img> whose src and alt are pulled from the attachment. max-width: 100% and height: auto are applied inline so the image scales correctly inside any layout.

Ferme la modale et ouvre directement la médiathèque WordPress. Choisissez une image ; à la sélection, l'élément est remplacé par un <img> dont le src et l'alt sont tirés de la pièce jointe. max-width: 100% et height: auto sont appliqués en inline pour que l'image s'adapte correctement à n'importe quelle mise en page.

What's preserved, what's not

Ce qui est conservé, ce qui ne l'est pas

  • Kept: AI-generated class names — the widget keeps the layout context (grid placement, alignment, etc.).
  • Dropped: Inline style attribute, data-naano-el id, custom CSS attribute. The widget starts visually clean and gets a new id on the next click-to-select.
  • Section dirty: The replacement is broadcast to the parent via the same naano-element-html-updated message used by every other DOM mutation — the section is marked unsaved, the toolbar's Save changes button appears.
  • Conservé : les noms de classes générés par l'IA — le widget garde le contexte de mise en page (placement grille, alignement, etc.).
  • Supprimé : l'attribut style inline, l'id data-naano-el, l'attribut CSS personnalisé. Le widget repart propre et reçoit un nouvel id au prochain clic.
  • Section modifiée : le remplacement est diffusé au parent via le même message naano-element-html-updated utilisé par toute autre mutation DOM — la section est marquée non sauvegardée, le bouton Enregistrer les modifications apparaît.
i

Designed to coexist with existing affordances

Conçu pour coexister avec les affordances existantes

The recycle button has its own hover scope (the hovered element), its own click handler (opens the widget modal, not the element editor), and its own z-index. None of the existing builder behaviours change — the section "+" button, inspect mode click-to-edit, inline contenteditable typing, all work exactly as before.

Le bouton ♻ a sa propre portée de survol (l'élément survolé), son propre gestionnaire de clic (ouvre la modale widget, pas l'éditeur d'élément), et son propre z-index. Aucun comportement existant du builder ne change — le bouton "+" de section, le clic-pour-éditer en mode inspection, la saisie contenteditable inline, tout fonctionne exactement comme avant.

Building a page

References & assets #

Références & assets #

Show the model what you can't easily describe.

Montrez au modèle ce que vous ne pouvez pas facilement décrire.

Screenshot references

Références screenshot

Click the 🖼️ icon on any section card. The WordPress media library opens. Select or upload an image. When the section is next generated, the plugin:

Cliquez sur l'icône 🖼️ sur n'importe quelle carte de section. La médiathèque WordPress s'ouvre. Sélectionnez ou téléversez une image. Lors de la prochaine génération de la section, le plugin :

  1. Fetches the attachment from disk.
  2. Resizes it to a maximum of 1024 × 1024 pixels using PHP GD's imagecopyresampled.
  3. Re-encodes it as JPEG at 75% quality.
  4. Base64-encodes the result.
  5. Injects it into the LLM message as an inline image content block (Claude, Gemini, OpenAI), or as a text note (Kimi, DeepSeek).
  1. Récupère la pièce jointe depuis le disque.
  2. La redimensionne à 1024 × 1024 pixels maximum via imagecopyresampled de PHP GD.
  3. La ré-encode en JPEG à 75 % de qualité.
  4. Encode le résultat en Base64.
  5. L'injecte dans le message LLM comme bloc de contenu image inline (Claude, Gemini, OpenAI), ou comme note textuelle (Kimi, DeepSeek).

URL references

Références URL

Click the 🔗 icon. Enter a URL and an optional note. URL references are injected into the system prompt as a structured "Reference websites" block — useful for aligning the model on a competitor's aesthetic, an industry standard, or a specific source of inspiration.

Cliquez sur l'icône 🔗. Saisissez une URL et une note optionnelle. Les références URL sont injectées dans le system prompt sous forme d'un bloc structuré « Sites de référence » — utile pour aligner le modèle sur l'esthétique d'un concurrent, un standard du secteur, ou une source d'inspiration spécifique.

Page assets

Assets de page

Number-referenced assets you can cite in instructions. Upload an image as asset #1; ask the model to "use asset #1 as the hero image". The plugin resolves the citation server-side when assembling the prompt.

Des assets référencés par numéro que vous pouvez citer dans vos instructions. Téléversez une image comme asset #1 ; demandez au modèle d'« utiliser l'asset #1 comme image hero ». Le plugin résout la citation côté serveur lors de l'assemblage du prompt.

URL redirections

Redirections URL

Named links — "Contact → /contact", "Pricing → /pricing". The model uses these real URLs in generated <a href> attributes instead of placeholder hashes.

Liens nommés — « Contact → /contact », « Tarifs → /pricing ». Le modèle utilise ces vraies URLs dans les attributs <a href> générés au lieu de hashes placeholder.

Building a page

Importing sections #

Importer des sections #

Reuse a header or footer from an existing Naano WP page instead of regenerating it.

Réutilisez un header ou un footer d'une page Naano WP existante plutôt que de le régénérer.

On the Create new page panel, expand Import from existing pages. Click Header or Footer next to any listed page to mark it for import (a check appears). Then click Generate full website. Imported sections are copied server-side from the source page's stored HTML, then AI-generated sections are added alongside them.

Dans le panneau Créer une nouvelle page, dépliez Importer depuis des pages existantes. Cliquez sur Header ou Footer à côté d'une page listée pour la marquer à importer (une coche apparaît). Puis cliquez sur Générer le site complet. Les sections importées sont copiées côté serveur depuis le HTML stocké de la page source, puis les sections générées par IA sont ajoutées à côté.

This matters because real sites tend to share their header and footer across every page. Regenerating either with the AI introduces drift — slightly different copy, slightly different links, slightly different markup. Importing keeps both pinned.

C'est important car les vrais sites partagent généralement leur header et leur footer sur toutes les pages. Régénérer l'un ou l'autre avec l'IA introduit de la dérive — texte légèrement différent, liens légèrement différents, balisage légèrement différent. L'import maintient les deux verrouillés.

Workflow

Translations #

Traductions #

A page per language, addressed by WordPress page hierarchy.

Une page par langue, organisée par hiérarchie de pages WordPress.

Each translated page is a child of the original. The language code becomes the slug. URLs are automatic.

Chaque page traduite est un enfant de l'original. Le code de langue devient le slug. Les URLs sont automatiques.

Original Original Spanish / Espagnol French / Français
/about/ /about/ /about/es/ /about/fr/
/ (homepage) / (page d'accueil) /es/ /fr/

Setup

Configuration

In Settings → Translation languages, click Add language and enter a code (es) and a label (Spanish). Save.

Dans Réglages → Langues de traduction, cliquez sur Ajouter une langue et saisissez un code (fr) et un libellé (Français). Enregistrez.

Creating a translation

Créer une traduction

In the pages list, click Translate on any original. Pick the target language; click Duplicate & translate. A child page is created with all sections pre-copied, and you're redirected straight to its builder. Use the AI to translate section by section — give it an instruction like "Translate every string to Spanish, keep the HTML structure identical".

Dans la liste des pages, cliquez sur Traduire sur n'importe quelle page originale. Choisissez la langue cible ; cliquez sur Dupliquer & traduire. Une page enfant est créée avec toutes les sections pré-copiées et vous êtes redirigé directement vers son builder. Utilisez l'IA pour traduire section par section — donnez-lui une instruction comme « Traduis tous les textes en français, garde la structure HTML identique ».

Language switcher

Sélecteur de langue

Once a page has at least one translation, a language <select> appears in the builder toolbar. Switching navigates immediately to that variant's builder.

Dès qu'une page a au moins une traduction, un <select> de langue apparaît dans la barre d'outils du builder. La sélection navigue immédiatement vers le builder de cette variante.

Workflow

Saving & publishing #

Enregistrer & publier #

Three buttons, three intents. Nothing is ambiguous.

Trois boutons, trois intentions. Rien n'est ambigu.

i

Save changes

Enregistrer les modifications

Orange button, visible only when there are unsaved manual edits. Writes every dirty section's HTML and the Global CSS textarea to the draft store. Does not publish.

Bouton orange, visible uniquement quand des modifications manuelles ne sont pas sauvegardées. Écrit le HTML de chaque section modifiée et le CSS global dans le brouillon. Ne publie pas.

ii

Publish

Publier

Assembles the final HTML server-side (with body-margin reset + global CSS) and writes it to the live WordPress page. Tick "Set as Homepage" in the modal to replace the WP front page.

Assemble le HTML final côté serveur (avec reset des marges + CSS global) et l'écrit dans la page WordPress en ligne. Cochez « Définir comme page d'accueil » dans la modale pour remplacer la page principale WP.

iii

Export HTML

Exporter HTML

Downloads the assembled HTML5 document as website.html. Self-contained, no theme, ready to host anywhere outside WordPress.

Télécharge le document HTML5 assemblé sous website.html. Autonome, sans thème, prêt à héberger n'importe où hors WordPress.

!

Don't close the tab with unsaved edits

Ne fermez pas l'onglet avec des modifications non sauvegardées

A beforeunload warning will prompt you if you try to navigate away with dirty sections. There is no auto-save: the draft store is only written when you click Save changes.

Un avertissement beforeunload s'affichera si vous essayez de naviguer ailleurs avec des sections modifiées. Il n'y a pas de sauvegarde automatique : le brouillon n'est écrit que quand vous cliquez sur Enregistrer les modifications.

Workflow

Global CSS #

CSS global #

Page-level CSS that survives section regenerations.

CSS au niveau de la page qui survit aux régénérations de sections.

A textarea in the left drawer, just under URL references. Accepts raw CSS. Injected into the assembled HTML after the platform's reset (html, body { margin: 0; padding: 0 } and box-sizing: border-box), so you can override anything the AI emits. Persisted alongside section edits when you click Save changes.

Une zone de texte dans le panneau gauche, juste sous les références URL. Accepte du CSS brut. Injecté dans le HTML assemblé après le reset de la plateforme (html, body { margin: 0; padding: 0 } et box-sizing: border-box), vous pouvez donc surcharger tout ce que l'IA émet. Persisté avec les éditions de sections quand vous cliquez sur Enregistrer les modifications.

Useful for setting global typography rules, body background, font-face imports, anything that needs to apply consistently across every section without being baked into individual section HTML.

Utile pour définir des règles typographiques globales, l'arrière-plan du body, des imports de font-face — tout ce qui doit s'appliquer de façon cohérente sur toutes les sections sans être intégré dans le HTML de chaque section.

i

Applied the moment the editor opens 2.3.4

Appliqué dès l'ouverture de l'éditeur 2.3.4

Your saved Global CSS is now injected into the very first live-preview render, so an existing page opens fully styled. Previously the CSS was fetched asynchronously after the first render, leaving the editor briefly un-styled until you touched the field.

Votre CSS global enregistré est désormais injecté dès le tout premier rendu de l'aperçu : une page existante s'ouvre donc entièrement stylée. Auparavant, le CSS était récupéré de façon asynchrone après le premier rendu, laissant l'éditeur brièvement sans style jusqu'à ce que vous touchiez le champ.

Workflow

Failed sections & retry #

Sections échouées & réessai #

A dedicated drawer for the sections that didn't survive their first generation.

Un panneau dédié aux sections qui n'ont pas survécu à leur première génération.

When a worker is killed mid-tick, the runner persists what it had, records the failure in _naano_failed_sections post meta (with a reason), and advances. Failed sections appear in a dedicated Failed sections drawer field with a one-click Retry button per entry. Each retry triggers a fresh single-section generation; recovered sections clear from the list automatically.

Quand un worker est interrompu en plein tick, le runner persiste ce qu'il avait, enregistre l'échec dans la post meta _naano_failed_sections (avec une raison) et avance. Les sections échouées apparaissent dans un champ dédié Sections échouées avec un bouton Réessayer en un clic par entrée. Chaque réessai déclenche une nouvelle génération de section unique ; les sections récupérées disparaissent automatiquement de la liste.

This means: a host kill during generation is not catastrophic. You finish the rest of the page, then come back to the failed sections one at a time when the host is calmer.

Cela signifie qu'une interruption par l'hébergeur pendant la génération n'est pas catastrophique. Vous terminez le reste de la page, puis revenez aux sections échouées une par une quand l'hébergeur est plus calme.

Configuration

Providers & API keys #

Fournisseurs & clés API #

Bring your own key. Your credentials stay on your server.

Apportez votre propre clé. Vos identifiants restent sur votre serveur.

Provider Default model Image support Get a key
Fournisseur Modèle par défaut Support image Obtenir une clé
Claude (Anthropic) claude-sonnet-4-20250514 Inline base64 console.anthropic.com
Gemini (Google) gemini-2.5-flash inlineData base64 aistudio.google.com/apikey
OpenAI gpt-5.5 image_url base64 platform.openai.com
Kimi (Moonshot) kimi-k2-0711-preview Text note Note texte platform.moonshot.cn
DeepSeek Latest available Dernière disponible Text note Note texte platform.deepseek.com

Keys are stored in wp_options and never leave your server except as the outbound HTTPS call to the provider. There is no telemetry, no third-party intermediary, no Naano WP server in the loop.

Les clés sont stockées dans wp_options et ne quittent jamais votre serveur sauf pour l'appel HTTPS sortant vers le fournisseur. Pas de télémétrie, pas d'intermédiaire tiers, aucun serveur Naano WP dans la boucle.

Test connection

Tester la connexion

Every settings panel has a Test connection button. It does a live ping to the provider with your key and model, returning the latency in milliseconds. If it fails, the error message comes straight from the provider.

Chaque panneau de réglages dispose d'un bouton Tester la connexion. Il effectue un ping en direct vers le fournisseur avec votre clé et votre modèle, retournant la latence en millisecondes. En cas d'échec, le message d'erreur vient directement du fournisseur.

Adding your own provider

Ajouter votre propre fournisseur

All adapters implement Naano_LLM_Provider_Interface. Create a class implementing the interface, register it in class-llm-router.php, and it shows up in the settings dropdown. No core code changes needed.

Tous les adaptateurs implémentent Naano_LLM_Provider_Interface. Créez une classe implémentant l'interface, enregistrez-la dans class-llm-router.php, et elle apparaît dans le menu déroulant des réglages. Aucune modification du code principal n'est nécessaire.

Configuration

Design variables #

Variables de design #

Brand-wide values injected into every prompt for consistent output.

Valeurs globales à la marque injectées dans chaque prompt pour un résultat cohérent.

See the Generating a page section for the standard list. Custom keys are supported — the model receives any key/value pair you define. Use them for anything you want the model to remember across sections: a slogan, a callout box phrasing, a specific CTA text, a forbidden word.

Consultez la section Générer une page pour la liste standard. Les clés personnalisées sont supportées — le modèle reçoit toute paire clé/valeur que vous définissez. Utilisez-les pour tout ce que vous souhaitez que le modèle retienne entre les sections : un slogan, une formulation de callout, un texte CTA spécifique, un mot interdit.

exampleprimary_color    #2776ea
font_family      Inter, sans-serif
tone             modern, technical
cta_text         Get started
forbidden_words  AI, artificial
Reference

Architecture #

Architecture #

Pure PHP. Every LLM call is a cURL. Every UI action is a jQuery AJAX. Every storage write is a postmeta.

PHP pur. Chaque appel LLM est un cURL. Chaque action UI est un AJAX jQuery. Chaque écriture est une postmeta.

User action → builder.js → AJAX (jQuery) → class-ajax-handler.php ↓ class-job-manager.php # transient + first cron tick ↓ class-job-runner.php # 1 LLM call per WP-Cron tick ↓ class-payload-compressor.php # HTML/CSS minif + section placeholders ↓ class-prompt-builder.php # vars + refs + assets + redirects ↓ class-llm-router.php # picks provider adapter ↓ ┌────────────────┬────────────────┬────────────────┬─────────────────┐ claude gemini openai kimi/deepseek ↓ ↓ ↓ ↓ cURL HTTPS cURL HTTPS cURL HTTPS cURL HTTPS ↓ class-html-sanitizer.php # strips script, on*, javascript: ↓ class-section-manager.php # writes postmeta ↓ JSON response ↓ builder.js → live preview iframe srcdoc refresh

Stored postmeta

Postmeta stockées

Key Scope Stores
Clé Portée Contenu
_naano_sections Every Naano WP page Toutes les pages Naano WP Array of {id, type, html, order} per section
_naano_global_css Every Naano WP page Toutes les pages Naano WP Raw CSS injected after the platform reset CSS brut injecté après le reset de la plateforme
_naano_failed_sections Every Naano WP page Toutes les pages Naano WP List of {section_id, section_type, reason} Liste de {section_id, section_type, reason}
_naano_lang Original + translations Original + traductions Language code (default, es, fr, …) Code de langue (default, es, fr, …)
_naano_translation_of Translations only Traductions uniquement Post ID of the original Post ID de l'original
_naano_page_html Every Naano WP page Toutes les pages Naano WP Assembled HTML written by Publish HTML assemblé écrit par Publier

HTML sanitisation

Assainissement HTML

Every LLM response passes through a sanitisation pipeline before storage: <script> tags removed, on* event attributes stripped, javascript: URIs rewritten. What lands in the database is provably clean.

Chaque réponse LLM passe par un pipeline d'assainissement avant stockage : balises <script> supprimées, attributs d'événements on* retirés, URIs javascript: réécrits. Ce qui atterrit en base de données est propre de façon prouvable.

Nonce protection

Protection par nonce

Every AJAX endpoint verifies a naano_builder_nonce nonce. Same standard WordPress idiom used by every well-behaved plugin.

Chaque endpoint AJAX vérifie un nonce naano_builder_nonce. Le même idiome WordPress standard utilisé par tout plugin bien conçu.

Reference

AJAX API #

API AJAX #

Every endpoint requires a valid naano_builder_nonce in the nonce POST field.

Chaque endpoint requiert un naano_builder_nonce valide dans le champ POST nonce.

Action Key parameters Returns
Action Paramètres clés Retourne
naano_generate_site page_id, page_name, description, sections[], imported_sections {job_id}
naano_update_section page_id, section_id, instruction, assets, redirects {job_id}
naano_poll_job job_id {status, data?, partial?, log?}
naano_save_section_html page_id, sections, global_css? {saved_count, page_id, global_css_saved}
naano_get_failed_sections page_id {page_id, failed_sections, global_css}
naano_test_connection provider, api_key, model {success, model, latency_ms}
naano_add_reference page_id, section_id, type, url, attachment_id, notes {references}
naano_remove_reference page_id, section_id, index {references}
naano_delete_section page_id, section_id {}
naano_reorder_sections page_id, order[] {}
naano_export_html page_id {html}
naano_save_as_page page_id, title, html? {page_id, edit_url, view_url, title}
naano_set_homepage page_id {}
naano_duplicate_for_translation page_id, lang Redirect to new page's builder
Reference

Hooks & filters #

Hooks & filtres #

Standard WordPress action and filter hooks for plugin authors and theme developers.

Hooks d'action et de filtre WordPress standard pour les auteurs de plugins et les développeurs de thèmes.

Hook Type Description
Hook Type Description
naano_before_generate action Before the LLM is called for full-site generation. Receives $page_id, $sections[]. Avant l'appel LLM pour la génération complète. Reçoit $page_id, $sections[].
naano_after_generate action After sections are stored. Receives $page_id, $parsed_sections[]. Après le stockage des sections. Reçoit $page_id, $parsed_sections[].
naano_before_update_section action Before a section update LLM call. Receives $page_id, $section_id. Avant un appel LLM de mise à jour de section. Reçoit $page_id, $section_id.
naano_after_update_section action After a section is updated. Receives $page_id, $section_id, $html. Après la mise à jour d'une section. Reçoit $page_id, $section_id, $html.
naano_system_prompt filter Modify the assembled system prompt before sending. Modifier le system prompt assemblé avant envoi.
naano_user_message filter Modify the user message before sending. Modifier le message utilisateur avant envoi.
naano_sanitized_html filter Modify cleaned HTML after sanitisation. Modifier le HTML nettoyé après assainissement.
Reference

Stored meta keys #

Clés meta stockées #

For migration scripts, custom queries, or programmatic page introspection.

Pour les scripts de migration, les requêtes personnalisées ou l'introspection programmatique de pages.

All Naano WP pages store their state in standard wp_postmeta rows. The keys are stable and documented — you can write tools against them.

Toutes les pages Naano WP stockent leur état dans des lignes wp_postmeta standard. Les clés sont stables et documentées — vous pouvez écrire des outils qui s'y appuient.

php// List every section on a Naano WP page
$sections = get_post_meta( $page_id, '_naano_sections', true );
foreach ( $sections as $section ) {
    echo $section['type'] . ': ' . strlen( $section['html'] ) . " bytes\n";
}
Reference

Troubleshooting #

Résolution de problèmes #

The small set of problems that come up regularly, and how to fix them.

Les problèmes qui reviennent régulièrement, et comment les résoudre.

The recycle button doesn't appear after updating

Le bouton ♻ n'apparaît pas après la mise à jour

The browser is serving the old builder.js from cache. WordPress version-strings every asset URL (builder.js?ver=…) — if the version is the same as before, browsers reuse the cached file. Bump NAANO_VERSION in the main plugin file, or hard-reload the builder page (Cmd/Ctrl + Shift + R).

Le navigateur sert l'ancien builder.js depuis le cache. WordPress ajoute la version du plugin dans chaque URL d'asset (builder.js?ver=…) — si le numéro de version est identique, le navigateur réutilise le fichier en cache. Incrémentez NAANO_VERSION dans le fichier principal du plugin, ou rechargez la page du builder en force (Cmd/Ctrl + Shift + R).

Generation is stuck on "queued"

La génération reste bloquée sur « en attente »

The WP-Cron tick hasn't fired yet. Visiting any front-end URL on your site will trigger WordPress's request-based cron and unblock the queue. If the issue persists, check that outbound HTTPS to your LLM provider is allowed by your host's firewall.

Le tick WP-Cron n'a pas encore été déclenché. Visiter n'importe quelle URL publique de votre site déclenchera le cron basé sur les requêtes WordPress et débloquera la file. Si le problème persiste, vérifiez que les connexions HTTPS sortantes vers votre fournisseur LLM ne sont pas bloquées par le pare-feu de l'hébergeur.

A section failed during generation

Une section a échoué pendant la génération

Look for the Failed sections drawer field at the bottom of the left drawer. Each entry has a Retry button. Most failures are transient (host kill, LLM rate limit) and succeed on retry.

Cherchez le champ Sections échouées en bas du panneau gauche. Chaque entrée possède un bouton Réessayer. La plupart des échecs sont transitoires (interruption par l'hébergeur, limite de débit LLM) et réussissent au second essai.

The API key test fails

Le test de clé API échoue

Click Test connection in Settings — the response contains the provider's actual error message. The most common causes are (1) wrong region for Gemini, (2) expired or rotated keys, (3) outbound firewall blocking HTTPS to the provider.

Cliquez sur Tester la connexion dans les Réglages — la réponse contient le message d'erreur exact du fournisseur. Les causes les plus fréquentes sont : (1) mauvaise région pour Gemini, (2) clé expirée ou révoquée, (3) pare-feu bloquant les connexions HTTPS sortantes vers le fournisseur.

Published page looks different from the preview

La page publiée est différente de l'aperçu

The preview iframe and the published page use the same assembled HTML, including the body-margin reset and your global CSS. If they diverge, the most likely cause is an active WordPress theme injecting styles. Naano WP publishes pages as raw HTML with no theme wrapping — if your theme is intercepting page rendering through filters, you may need to whitelist Naano WP-published pages.

L'iframe d'aperçu et la page publiée utilisent le même HTML assemblé, incluant la réinitialisation des marges et votre CSS global. Si une divergence apparaît, la cause la plus probable est un thème WordPress actif qui injecte des styles. Naano WP publie les pages en HTML brut sans encapsulation par le thème — si votre thème intercepte le rendu via des filtres, vous devrez peut-être mettre les pages Naano WP en liste blanche.


Need help, found a bug, or want to contribute? Open an issue on GitHub. Besoin d'aide, vous avez trouvé un bug, ou vous souhaitez contribuer ? Ouvrez une issue sur GitHub.