Skip to content

Comunicazione Iframe - Navigation

Panoramica

Questo documento descrive il sistema di navigazione dell'applicazione React dall'iframe. L'iframe può chiamare una funzione sul parent window per navigare a una route specifica dell'applicazione principale.

Architettura

Hook: useIframeNavigation

L'hook useIframeNavigation è responsabile di:

  1. Registrare l'oggetto navigation sul window globale
  2. Fornire la funzione navigateTo che l'iframe può chiamare per navigare
  3. Validare e normalizzare il path della route
  4. Pulire l'oggetto navigation quando il componente viene smontato

Type Declaration

Il file app/types/window.d.ts include la definizione TypeScript per l'oggetto navigation:

typescript
declare global {
    interface Window {
        /**
         * Oggetto per la navigazione dall'iframe.
         * L'iframe può chiamare questo metodo per navigare a una route specifica.
         */
        navigation?: {
            /**
             * Naviga a una route specifica nell'applicazione React
             * @param path - Il path della route (es. "/r/modulo/vendite" o "r/modulo/vendite")
             */
            navigateTo: (path: string) => void;
        };
    }
}

Utilizzo

Nel Parent Window (React App)

L'hook useIframeNavigation viene utilizzato nell'AuthenticatedLayout:

typescript
export function AuthenticatedLayout({ children, minimalMode = false }: AuthenticatedLayoutProps) {
    // ... altri hook ...

    // Registra l'oggetto navigation sul window per permettere la navigazione dall'iframe
    useIframeNavigation();

    // ... resto del componente ...
}

Nell'Iframe (PHP/JavaScript)

L'iframe può navigare chiamando:

javascript
window.parent.navigation.navigateTo('/r/modulo/vendite');

Esempi di Utilizzo

javascript
// Navigazione a un modulo specifico
window.parent.navigation.navigateTo('/r/modulo/vendite');

// Navigazione alla home (welcome)
window.parent.navigation.navigateTo('/welcome');

// Navigazione con path senza slash iniziale (viene normalizzato automaticamente)
window.parent.navigation.navigateTo('r/modulo/clienti');

// Navigazione a una route con parametri
window.parent.navigation.navigateTo('/r/ordini/dettaglio/123');

Esempio PHP

php
<script>
// Navigazione dopo un'azione (es. salvataggio completato)
function onSaveComplete() {
    window.parent.navigation.navigateTo('/r/modulo/lista-ordini');
}

// Navigazione con link
echo '<a href="#" onclick="window.parent.navigation.navigateTo(\'/r/modulo/clienti\'); return false;">
    Vai ai Clienti
</a>';
</script>

Validazione e Normalizzazione

L'hook esegue automaticamente:

  1. Validazione del path: Verifica che il path sia una stringa non vuota
  2. Normalizzazione: Aggiunge "/" all'inizio se mancante
  3. Gestione errori: Logga errori se la navigazione fallisce
typescript
// Esempi di normalizzazione
'r/modulo/vendite''/r/modulo/vendite'
'/r/modulo/vendite''/r/modulo/vendite'  (già normalizzato)
'welcome''/welcome'

Debug

Quando l'iframe chiama navigateTo, dovresti vedere nella console:

================================================================================
[useIframeNavigation] 🎯 navigateTo chiamata dall'iframe!
[useIframeNavigation] 📍 path: /r/modulo/vendite
[useIframeNavigation] 🔄 Navigazione a: /r/modulo/vendite
[useIframeNavigation] ✅ Navigazione completata!
================================================================================

Al mount dell'hook:

[useIframeNavigation] Hook montato, registrazione navigation...
[useIframeNavigation] ✅ Oggetto navigation registrato sul window
[useIframeNavigation] ✅ window.navigation.navigateTo disponibile: function

Test

Test Manuale

  1. Avvia l'applicazione: npm run dev
  2. Naviga a una pagina con iframe: /test-iframe o /r/qualsiasi-modulo
  3. Apri la console del browser
  4. Dall'iframe, esegui:
    javascript
    window.parent.navigation.navigateTo('/welcome');
  5. Verifica che l'applicazione navighi alla route specificata

Test con la pagina di test

La pagina /test-iframe include pulsanti per testare la navigazione:

html
<button onclick="window.parent.navigation.navigateTo('/welcome')">
    Test Navigation - Welcome
</button>
<button onclick="window.parent.navigation.navigateTo('/r/modulo/test')">
    Test Navigation - Module
</button>

Casi d'Uso

1. Redirect dopo Login nell'iframe

php
<?php
// Dopo login PHP nell'iframe
if ($login_successful) {
    echo '<script>window.parent.navigation.navigateTo("/r/dashboard");</script>';
}
?>

2. Navigazione da Menu nell'iframe

javascript
// Menu nell'iframe che naviga l'app principale
const menuItems = [
    { label: 'Vendite', route: '/r/modulo/vendite' },
    { label: 'Clienti', route: '/r/modulo/clienti' },
    { label: 'Ordini', route: '/r/modulo/ordini' }
];

menuItems.forEach(item => {
    const link = document.createElement('a');
    link.textContent = item.label;
    link.href = '#';
    link.onclick = (e) => {
        e.preventDefault();
        window.parent.navigation.navigateTo(item.route);
    };
    menu.appendChild(link);
});

3. Navigazione Condizionale

javascript
// Navigazione basata su permessi utente
function openModule(moduleName) {
    if (hasPermission(moduleName)) {
        window.parent.navigation.navigateTo('/r/modulo/' + moduleName);
    } else {
        alert('Non hai i permessi per accedere a questo modulo');
    }
}

Note sulla Sicurezza

  • La comunicazione avviene tramite window.parent, funziona solo se l'iframe è sullo stesso dominio o configurato con CORS
  • Il path viene validato per assicurarsi che sia una stringa valida
  • L'oggetto navigation viene rimosso quando il componente viene smontato per evitare memory leaks
  • Gli errori durante la navigazione vengono catturati e loggati senza bloccare l'applicazione

Troubleshooting

La navigazione non funziona

  1. Verifica che l'hook sia montato: Controlla i log nella console
  2. Verifica same-origin policy: L'iframe deve essere sullo stesso dominio
  3. Controlla il path: Deve essere una stringa valida
  4. Verifica il timing: Assicurati che l'oggetto navigation sia già disponibile quando lo chiami

Come verificare se navigation è disponibile

javascript
// Nell'iframe
if (window.parent && window.parent.navigation) {
    console.log('✅ Navigation disponibile');
    window.parent.navigation.navigateTo('/welcome');
} else {
    console.error('❌ Navigation non disponibile');
}

Integrazione con React Router

L'hook utilizza il hook useNavigate di React Router, quindi supporta:

  • Navigazione con history
  • Pulsante back/forward del browser
  • Route nidificate
  • Route dinamiche con parametri
  • Query parameters (se inclusi nel path)
javascript
// Esempi supportati
window.parent.navigation.navigateTo('/r/ordini?status=pending');
window.parent.navigation.navigateTo('/r/clienti/123/dettagli');

Prossimi Passi

  1. State Management: Considerare il passaggio di stato durante la navigazione (se necessario)
  2. Navigazione con Replace: Aggiungere opzione per replace invece di push
  3. Callback: Aggiungere callback per notificare l'iframe quando la navigazione è completata
  4. Validazione Route: Validare che la route esista prima di navigare

Relazioni con Altri Sistemi

  • useTopbarMenu: Gestisce il menu della topbar
  • useTopbarMessages: Gestisce i messaggi non letti
  • useTopbarCart: Gestisce il carrello
  • AuthenticatedLayout: Contiene tutti gli hook di comunicazione iframe

Documentazione Elerama Frontend