janeberl Jan Eberl .de

React mit react-router im Unterordner

Nach etwas Fummeln und Doku-wälzen hat's nun endlich funktioniert. Hier eine knappe Zusammenfassung, wie man eine React-App mit React Router in einem Unterordner betreibt.

Das Problem:

Sobald man eine React-App im Unterordner betreibt, schlägt spätestens bei Verwendung des MemoryRouter (statt BrowserRouter) das URL-Matching nicht mehr an. Da die Doku zum React Router bestenfalls gut gemeint, im Allgemeinen aber lückenhaft ist, bedarf es hier etwas Fummelei.

Die Lösung:

Die Lösung besteht aus 4 einfachen Punkten:

1. basename des Routers setzen

Die property basename setzt einen für den <Router /> global gültigen Startpunkt:

<Router basename={'/subdirectory'}>
    <Route path='/' component={Home} />
    // ...
</Router>
2. Korrekte homepage setzen

In der package.jsongibt es eine property namens homepage. Euer build script kann diese property dazu verwenden, die korrekte URL in euer Kompilat zu parsen, damit später beim production build alles an die richtige Stelle zeigt.

"homepage": "https://myapp.com/subdirectory",
3. Routen updaten

Die homepageproperty aus der package.jsonkönnen wir glücklicherweise auch in unserem JSX verwenden. Exponiert wird die homepagedurch die Variable process.env.PUBLIC_URL zur Build-Zeit.
Jetzt nehmen wir die Variable, und füttern unsere Routen damit:

<Router basename={'/subdirectory'}>  
    <Route path={'${process.env.PUBLIC_URL}/'} component={Home} />
    <Route path={'${process.env.PUBLIC_URL}/services'} component={Services} />
    <Route path={'${process.env.PUBLIC_URL}/shop'} component={Shop} />
    <Route path={'${process.env.PUBLIC_URL}/about'} component={About} />
</Router> 

Anmerkung: Wenn ihr separate build-Prozesse für development und production habt, könnt ihr das gefahrlos direkt hinzufügen.

4. Links anpassen

An allen Stellen in der App, an denen navigiert wird, muss nun auch die globale URL gesetzt werden, damit das Routing weiterhin funktioniert. Also in allen <Link />s und <Redirect />s, sowie auch überall dort, wo ihr eventuall programmatisch navigiert (this.props.history.push('${process.env.PUBLIC_URL}/zielseite')).

Fertig. Mehr über den react Router erfahrt ihr in der Doku