How to get index.html from a react bundle location:
You can set resource.location in application.properties to whatever you want. For testing puproses I set it to a build folder of my react project. Then i only npm run build and new changes are visible.
@Configuration
@EnableWebMvc
@Slf4j
public class WebConfig implements WebMvcConfigurer {
@Value("${resource.location:}")
String resourceLocation;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!resourceLocation.isEmpty()) {
log.info("static data path 'file:" + resourceLocation + "/static/'");
registry.addResourceHandler("/static/**")
.addResourceLocations("file:" + resourceLocation + "/static/");
registry.addResourceHandler("/*.js")
.addResourceLocations("file:" + resourceLocation + "/");
registry.addResourceHandler("/*.json")
.addResourceLocations("file:" + resourceLocation + "/");
registry.addResourceHandler("/*.ico")
.addResourceLocations("file:" + resourceLocation);
registry.addResourceHandler("/index.html", "/")
.addResourceLocations("file:" + resourceLocation + "/index.html");
}
}
How to redirect from spring to react path:
I have created errorHandler so that i catch all paths that are not handled, and then i return index.html with parameter path.
@Order(Ordered.HIGHEST_PRECEDENCE)
@ControllerAdvice
@Slf4j
public class RestExceptionHandler extends ResponseEntityExceptionHandler {
@Override
protected ResponseEntity<Object> handleNoHandlerFoundException(NoHandlerFoundException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
log.info("no handler found for " + ex.getRequestURL());
headers.add("location", "index.html?path="+ex.getRequestURL());
return new ResponseEntity<>(null, headers, HttpStatus.SEE_OTHER);
}
}
On react side on index.html page i get path and send it as prop to NavigationBar
let path = window.location.search
console.log(path)
let pathMatch = path.match("(path=)(\\S*?)(&|$)")
if (pathMatch) {
path = pathMatch[2]
}
ReactDOM.render(
< React.StrictMode >
<BrowserRouter>
<NavigationBar path={path} />
</BrowserRouter>
</React.StrictMode >,
document.getElementById('root')
);
And then in NavigationBar class i set state in constructor state of redirectToPath to true if prop.path!==undefined.
and in render method i call redirect only once if needed:
render() {
if (this.state.redirectToPath) {
this.setState({ redirectToPath: false });
return (<Redirect to={this.props.path}/>)
}
return ( regular render....)
So when i want to redirect from spring app to localhost/reactModule.
- redirect to localhost/reactModule
- error handler catch no handler exception and redirect to localhost/index.html?path=reactModule
- index.html gets path and add it as property to its child
- Child element redirects correctly if path exists