Is it were possible to have default routes in Next.js so all routes or a whitelist of routes will all go to a specific page.
For my project the idea is to use Next.js to build the marketing website, sign up and sign in process, and then to have a Next.js page that would boot up an SPA (probably using create-react-app and react-router) so that any route which isn't a Next.js page would assume that instead its a route in the SPA and would therefore direct to that page which would boot up the SPA
One way that seems to work is to create a custom 404 page. https://nextjs.org/docs/advanced-features/custom-error-page
Every route that is not a recognised next.js route will call this page, but will not redirect (change the browser URL) which is exactly what's wanted when booting up an SPA.
I just added a app/page.tsx (pages/page.tsx) and returned the default component like this: (I just needed a default page / entry-page for '/')
'use client';
import AboutUs from './aboutus/page'
const DfltPage = () => {
return (<AboutUs/>)
}
export default DfltPage;
This worked fine for me.
Related
I have a link in my react app supposed to open in an another page a pdf but google chrome is opening the react application instead of my api that renders the pdf
The url of my pdf is /api/file/:_id and my react app is at /
Express routes below :
app.use("/api/file", fileRouter)
app.get("*", (req, res) => {
return res.sendFile(path.join(__dirname, "/front/build/index.html"))
})
When I click on my link
link
chrome is opening the react page and not my file whereas Safari open my file.
Thanks for your help.
In react you should use <Link> component from react-router-dom. react-router
If you want to redirect to outside website, you have to do something like: <Link to={{pathname: "//www.stackoverflow.com/"}} target="_blank">StackOverflow</Link>
We have a react app already built with CRA and Router. We want to implement SSR on it so that we can have proper SEO and social media support. I have seen and tried a number of techniques available for this but none of these seems to work.
We made our app in such a way that a lot of it actually depends upon browser to work properly, for example on the window object. One technique (kind of) worked but running the code on the server side gives the error;
ReferenceError: 'window' is not defined
The main reason we want to implement SSR is SEO and social media recognition of the site. We are adding meta tags dynamically (using React Hemlet) so facebook, twitter etc. are unable to get the tags.
So now the questions are;
Is there a proper way to implement SSR on an already built react site?
Is there any alternative we can use? The site has a large amount of resources fetched from remote API endpoints so prerendering is not an option.
You can always implement SSR on a built react site. You will keep your components as unchanged.
However you may need to make modifications at the entry point of your application. And also you will need to create an embedded server in your application which is gonna be your SSR.
For that you will need to make your own webpack configuration.
You may need a developer for that ;)
If you want SSR because of SEO. I would like to use Prerender https://prerender.io/ . This one let our site support SEO even though it's built by React.
Adding to the first answer, SSR does not execute useEffect(), componentDidMount(), and componentDidUpdate(). However, SSR will execute render(). Therefore, take some time to move window and document from render() to useEffect(), componentDidMount(), or componentDidUpdate().
If those objects are used in third-party dependencies, don't import them on the server-side. Instead, on the server-side, render something else (e.g. ComponentA), then on the client-side, use dynamic imports with React lazy to render third-party components with fallback set to ComponentA. For example:
// import ThirdPartyComponent from "some-third-party-package"; /* remove this */
const { IS_SERVER_SIDE } = process.env;
const ServerSideComponent = () => <div>This is server side component</div>;
let ThirdPartyComponent;
if (!IS_SERVER_SIDE) {
ThirdPartyComponent = React.lazy(() => import("some-third-party-package"));
}
class YourPage extends React.Component {
render() {
if (IS_SERVER_SIDE || !ThirdPartyComponent) {
return <ServerSideComponent />;
}
return (
<React.Suspense fallback={<ServerSideComponent />}>
<ThirdPartComponent />
</React.Suspense>
}
}
If you're using an express server you can try the SSR For bots middleware ssr-for-bots I implemented it after stumbling on the same problem,I wanted SSR only because of SEO.
I have a react application that sits on the Laravel 5.4 framework.
The problem I'm having is that on a page refresh with a URL such as https://app.com/{url}/{slug} breaks the application.
Here is my router component that sits in App.js
<Router>
<div className="App__container container-fluid">
<Navigation />
<Switch>
<Route path="/films" component={FilmsContainer}/>
<Route path="/films/:slugname" component={FilmPage}/>
</Switch>
</div>
</Router>
Refreshing the page through the browser when the FilmsContainer component is displayed works properly as I have the routes for Laravel configured to return the main layout that holds the React application whenever any web route is hit via this code here.
Route::get('{slug}', function() {
return view('main');
})->where('slug', '(?!api)([A-z\d-\/_.]+)?');
However, an issue comes when this Link component is hit,
<NavLink className="btn btn-success" to={`/films/${slugName}`}>View Film</NavLink>
On the first click, react router successfully renders the component with the correct url, for example: https://www.app.com/films/this-film-name.
However when I refresh the page on this url, the react application breaks,
returning an error in the Javascript console:
Uncaught SyntaxError: Unexpected token < app.js:1
When refreshing the page on any url that matches the www.app.com/{route}/{slug}
pattern, the app breaks and nothing is rendered, all I see is a blank white page in the browser.
I've tried using browserHistory and also setting other routes in Laravel web routes file, such as:
Route::get('films/{slug}', function() {
return view('main');
})->where('slug', '(?!api)([A-z\d-\/_.]+)?');
to try and match the extra params in the routes and serve the main html file that holds the application.
None of this seems to be working and I'm a little confused, is this a Laravel issue? Do I have react router configured incorrectly? Any advice would be greatly appreciated, thanks!
It looks to me like you may be calling app.js from a relative path. Like <script src="app.js"></script> and so in the films directory it's actually calling https://www.app.com/films/app.js and getting a 404, but Laravel's sending HTML from that https://www.app.com/films/app.js URL, hence the Uncaught SyntaxError: Unexpected token < error.
When React Router is changing the browser URL from page to page, that is all done on the client side. You make 1 request to the server for index.html (or index.php), and the rest is taken care of by React Router. Click the button, change the URL, change the content to display, all within index.html.
When you refresh, however, you're making a new request to the server for this weird URL it doesn't know how to handle -- it only knows how to serve up your main index file. I'm not too familiar with PHP, but to fix this you just need to tell your server to fall back to your main file. This post might guide you in the right direction. When Laravel gets a URL it doesn't know how to handle, it should fall back to your index file, which will get served up and then in the browser React Router will handle the routing.
I'm using the new router (not router-deprecated) in Angular2 RC1. I need to be able to load a JSON configuration file before the app continues loading. I'm using a Config class to grab my JSON configuration, but the problem is, I do not want the router-outlet to load until my configuration has completed loading.
I tried wrapping the <router-outlet> with an *ngIf, only to come across this issue: https://github.com/angular/angular/issues/8539
I also tried extending the <router-outlet>, per this article, but with no luck (doesn't work with RC1)
Angular1 has a way to "reload" the route, but this doesn't seem to be present in NG2.
How can I do this? How can I load my JSON config file after the app has loaded, and the render the app after the configuration has finished? Has anyone else successfully done this?
In the new router (>= RC.3) https://angular.io/docs/ts/latest/api/router/index/Router-interface.html#!#resetConfig-anchor resetConfig can be used
router.resetConfig([
{ path: 'team/:id', component: TeamCmp, children: [
{ path: 'simple', component: SimpleCmp },
{ path: 'user/:name', component: UserCmp }
] }
]);
For your case I would initialize the router with some dummy route and dummy component, then after your JSON is available load new routes and navigate to the new default route.
https://github.com/angular/angular/issues/11437#issuecomment-245995186 provides an RC.6 Plunker
How about considering a loading page? That way, if your data isn't fully loaded yet, it shows a loading page instead of your route.
See this question for suggestions on how to implement a loading screen in Angular2.
Update:
In the other hand, I just find out that we can pre load a data using a route resolver. I'm still learning about it too, and this angular documentation might help.
I have created a sample app using #RouteConfig and it working fine. See the url changes and view added according to configuration, but when I am refreshing the page it's showing a 404 error.
I am using WebStorm IDE to build and run the app.
The same problem happens with given live example on angular.io.
I have downloaded the sample code example for routing and navigation in AngularJS2 on https://angular.io/resources/live-examples/router/ts/plnkr.html which given on angular.io and opened the project into WebStorm and ran it.
It working fine but after doing some routing and then refreshing the page it shows a 404 Error.
Angular 2 (in default) uses html5 pushState for router states. Which means actual url changes between states.
For example for home page you may be in url: / and you click something, your address becomes /newAddress. This is done using pushState api and pure frontend. But if you refresh page, server tries to render the resource on /newAddress but, of course, there is no such resource on server. You need to configure your server to host / whatever the url is, but I don't know if it is possible or not in WebStorm internal server. You can install and use superstatic npm package.
OR... You can configure Angular 2 to use hashbang based urls (such as /#/ and /#/newAddress). That way, you hit / every time from perspective of backend.
This page has detailed explanation.
Make sure you've included a
<base href="/">
in your head section. Aside from that, we're going to need more information.
This will solve your problem, add this to your bootstrap
import {bootstrap} from 'angular2/platform/browser';
import {provide} from 'angular2/core';
bootstrap(AppComponent,[ROUTER_PROVIDERS,
provide(LocationStrategy, { useClass: HashLocationStrategy })]);
Now whenever you hit a refresh or a hard reload the default component defined in #RouteConfig would be loaded.
in your AppComponent :
#RouteConfig([
{path: '/login', name : 'Login' , component : Login , useAsDefault: true}
])