Guardando i commenti sulla risposta accettata e la natura generica di questa domanda ("non funziona"), ho pensato che questo potesse essere un buon posto per alcune spiegazioni generali sui problemi qui coinvolti. Quindi questa risposta è intesa come informazione / elaborazione di sfondo sul caso d'uso specifico del PO. Per favore abbi pazienza.
Lato server vs lato client
La prima cosa importante da capire a riguardo è che ora ci sono 2 posti in cui viene interpretato l'URL, mentre in passato ne esisteva solo 1 nei "vecchi tempi". In passato, quando la vita era semplice, alcuni utenti inviavano una richiesta http://example.com/about
al server, che controllava la parte del percorso dell'URL, stabiliva che l'utente stava richiedendo la pagina about e quindi restituiva quella pagina.
Con il routing lato client, che è ciò che React-Router fornisce, le cose sono meno semplici. Inizialmente, il client non ha ancora caricato alcun codice JS. Quindi la primissima richiesta sarà sempre al server. Ciò restituirà quindi una pagina che contiene i tag di script necessari per caricare React e React Router ecc. Solo quando tali script sono stati caricati inizia la fase 2. Nella fase 2, quando l'utente fa clic sul 'Chi siamo' link di navigazione, per esempio, l'URL è cambiato solo localmente a http://example.com/about
(reso possibile dalla API Storia ), ma nessuna richiesta al server è fatta. Invece, React Router fa la sua parte sul lato client, determina quale vista React visualizzare e renderizza. Supponendo che la tua pagina di informazioni non debba effettuare chiamate REST, è già stata fatta. Sei passato da Home a Chi siamo senza che sia stata attivata alcuna richiesta del server.
Quindi, fondamentalmente, quando si fa clic su un collegamento, viene eseguito JavaScript che manipola l'URL nella barra degli indirizzi, senza causare un aggiornamento della pagina , che a sua volta fa sì che React Router esegua una transizione di pagina sul lato client .
Ma ora considera cosa succede se copi e incolli l'URL nella barra degli indirizzi e lo mandi via e-mail a un amico. Il tuo amico non ha ancora caricato il tuo sito web. In altre parole, è ancora nella fase 1 . Nessun React Router è ancora in esecuzione sulla sua macchina. Quindi il suo browser farà una richiesta al serverhttp://example.com/about
.
Ed è qui che inizia il tuo problema. Fino ad ora, potresti cavartela semplicemente posizionando un HTML statico nella webroot del tuo server. Ma ciò darebbe 404
errori per tutti gli altri URL quando richiesto dal server . Quegli stessi URL funzionano bene sul lato client , perché React Router sta eseguendo il routing per te, ma falliscono sul lato server a meno che tu non li capisca.
Combinazione di routing lato server e lato client
Se si desidera che l' http://example.com/about
URL funzioni sia sul lato server che sul lato client, è necessario impostare percorsi per esso sia sul lato server che sul lato client. Ha senso giusto?
Ed è qui che iniziano le tue scelte. Le soluzioni vanno dal bypassare completamente il problema, attraverso un percorso generale che restituisce il bootstrap HTML, all'approccio isomorfo completo in cui sia il server che il client eseguono lo stesso codice JS.
.
Bypassare il problema del tutto: Hash History
Con Hash History anziché Browser History , il tuo URL per la pagina about sarebbe simile al seguente:
http://example.com/#/about
La parte dopo il #
simbolo hash ( ) non viene inviata al server. Quindi il server vede http://example.com/
e invia solo la pagina dell'indice come previsto. React-Router raccoglierà la #/about
parte e mostrerà la pagina corretta.
Lati negativi :
- URL "brutti"
- Il rendering sul lato server non è possibile con questo approccio. Per quanto riguarda l'ottimizzazione per i motori di ricerca (SEO), il tuo sito web è costituito da una singola pagina con quasi nessun contenuto.
.
Catch-all
Con questo approccio si fa uso cronologia del browser, ma solo impostare un catch-all sul server che invia /*
a index.html
, in modo efficace dando più o meno la stessa situazione con Hash Storia. Hai comunque URL puliti e potresti migliorare questo schema in un secondo momento senza dover invalidare tutti i preferiti dell'utente.
Lati negativi :
- Più complesso da configurare
- Ancora nessun buon SEO
.
Ibrido
Nell'approccio ibrido espandi lo scenario generale aggiungendo script specifici per percorsi specifici. Potresti creare alcuni semplici script PHP per restituire le pagine più importanti del tuo sito con contenuti inclusi, in modo che Googlebot possa almeno vedere cosa c'è sulla tua pagina.
Lati negativi :
- Ancora più complesso da configurare
- Solo un buon SEO per quei percorsi che ti danno il trattamento speciale
- Duplicazione del codice per il rendering del contenuto su server e client
.
Isomorfo
Che cosa succede se utilizziamo Node JS come nostro server in modo da poter eseguire lo stesso codice JS su entrambe le estremità? Ora, abbiamo tutti i nostri percorsi definiti in una singola configurazione di reazione-router e non abbiamo bisogno di duplicare il nostro codice di rendering. Questo è "il santo graal" per così dire. Il server invia lo stesso markup identico a quello che avremmo se la transizione della pagina fosse avvenuta sul client. Questa soluzione è ottimale in termini di SEO.
Lati negativi :
- Il server deve (essere in grado di) eseguire JS. Ho sperimentato Java icw Nashorn ma non funziona per me. In pratica, ciò significa principalmente che è necessario utilizzare un server basato su Node JS.
- Molte problematiche ambientali difficili (utilizzo
window
sul lato server ecc.)
- Ripida curva di apprendimento
.
Quale dovrei usare?
Scegli quello con cui puoi cavartela. Personalmente penso che il catch-all sia abbastanza semplice da impostare, quindi sarebbe il mio minimo. Questa configurazione ti consente di migliorare le cose nel tempo. Se stai già utilizzando Node JS come piattaforma server, indagherei sicuramente a fare un'app isomorfa. Sì, all'inizio è difficile, ma una volta capito è in realtà una soluzione molto elegante al problema.
Quindi sostanzialmente, per me, sarebbe questo il fattore decisivo. Se il mio server gira su Node JS, diventerei isomorfo; altrimenti sceglierei la soluzione Catch-all e la espanderei semplicemente (soluzione ibrida) man mano che il tempo avanza e i requisiti SEO lo richiedono.
Se vuoi saperne di più sul rendering isomorfo (chiamato anche 'universale') con React, ci sono alcuni buoni tutorial sull'argomento:
Inoltre, per iniziare, ti consiglio di guardare alcuni kit di partenza. Scegline uno che corrisponda alle tue scelte per lo stack tecnologico (ricorda, React è solo la V in MVC, hai bisogno di più cose per creare un'app completa). Inizia guardando quello pubblicato da Facebook stesso:
O scegli uno dei tanti dalla community. C'è un bel sito ora che cerca di indicizzarli tutti:
Ho iniziato con questi:
Attualmente sto usando una versione casalinga del rendering universale che è stata ispirata dai due kit di base sopra, ma ora non sono aggiornati.
Buona fortuna con la tua ricerca!