I'm trying to redirect a user with router.push(url); where an url is like the following: [:lang]/something/[...dynamicRouteParams]?searchParam=true.
There's an issue, that a user is redirected to a page with URL: [:lang]/something/[...dynamicRouteParams]?searchParam=true&lang=something&dynamicRouteParams=item1&dynamicRouteParams=item2.
How can I get rid of the search params related to route params?
Yes, you can do this with getServerSideProps or getStaticProps
export async function getServerSideProps({res, params }) {
//get data you need from API or params
const data = api or params
//now redirect to a link with params
res.setHeader("location", "/URL_WITH_PARAMS");
// you still need 'return' because of react structure
return {
props: {
data
},
}
}
Notice: Router.push() only client-side (rendering)
P.S You can pass any params and retrieve it page you land. Check documentation
Related
I have a project with react js and next js. I am developing a dynamic page, with getStaticPaths and getStaticProps. So I am fetching most of the data in getStaticProps to make the page be rendered on server side.
But there are some data which I can't fetch on server side, because it needs token which is stored in local storage.
The question is, if I use useEffect hook to fetch those data on client side, does this all process make any advantage for SEO?
Or I have to change structures, and store token in cookies to fetch all data on server side?
Update:
I want to check if user is logged in, and based on the result, show the page in different styles. But no user-related data is going to be rendered.
Right now, my code looks like this:
export default function BookDetail(props) {
const [isLoggedIn, setIsLoggedIn] = React.useState(false);
React.useEffect(() => {
// It captures token from cookies
const token = getCookie("token");
// Then I need to confirm that token is valid from backend
if (token) {
setIsLoggedIn(true);
}
}, []);
return (
<div>
{ !isLoggedIn ? (
{props.res.data.title}
<br/>
{props.res.data.description}
) : (
{props.res.data.title}
<br/>
<button type="button" onclick={()=>{window.location.href='http://example.com';}}
)}
</div>
);
}
If you need a token to fetch said data, that data is probably related to the user? Hence, doesn't and shouldnt be considered with SEO.
If your data is not specifically for the user. Consider making it accessable without token.
Edit based on the comments here:
Fetching data inside useEffect will absolutely affect SEO. You want to display part of a book (text) for users that are not logged in. You check if users are logged in by a request from the useEffect, this is fine and standard.
If you want to Google to be able to read your book-text with crawlers you can not fetch it in useEffect, I suggest the following:
in your getStaticProps: Fetch the data (book text) and pass it to your page. Display this information by default.
Then in your useEffect you check if the user is logged in. If they are --> remove the text and render a button instead.
This way, Google will read it as you intend, while logged in users will only see a button.
You can check no problem on the server side whether a user is logged in only when you use getServerSideProps - getStaticProps are executed at a built time so there is no communication with whatever user inputs into the UI simply because thats a different time frame: building the app on the server, only when the app is built user can interact with it.
But getServerSideProps are not executed at a built time, yet there are still executed on the server side and since useEffect is a frontend API it won't work there. So there are two ways:
If you use NextAuth - you can use getServerSideProps and on the context object you have 'req' property and the property passed to the getSession function (you need to import that function) will tell you whether user has a session or not. Here is an example code snipet:
import { getSession } from "next-auth/react";
// some code here like your frontend component
export const getServerSideProps = async (context) => {
const { req, res } = context;
const session = await getSession({ req: req });
if (!session) {
return {
redirect: { destination: "/", permanent: false },
};
}
const email = session.user.email;
return {
props: { email: email, session },
};
};
Here is more on the subject from the official next docs:
https://nextjs.org/docs/authentication
If you don't use NextAuth I am sure you can attach your token to the context object like in the example above and read it in getServerSideProps except not use getSession as that is NextAuth API. haven't done it though.
I am currently trying to find the page that the user has came from to enter this current one in the server side props, im not sure if thats possible? or are there any ways that i could access that
TLDR: get the url which user is coming from and not where is going to, example:
coming from: http://localhost:6060/product/id/55555-62/
going to: http://localhost:6060/products/
I would like to access the id query, in the /products/ getServerSideProps
export const getServerSideProps = wrapper.getServerSideProps(store => async ({ req }) => {
console.log(req);
return {
props: {},
};
});
https://nextjs.org/docs/api-reference/data-fetching/get-server-side-props#context-parameter
resolvedUrl: A normalized version of the request URL that strips the _next/data prefix for client transitions and includes original query values.
export const getServerSideProps = (ctx) => {...}
Inside ctx you can find params, query, resolvedUrl etc
Would the referrer enough for the thing you needed it for?
req.headers.referer
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer
When using Next.js dynamic routing I'm trying to make an SWR fetch request using the routing query object, but my SWR fetch request is being called before the query object is set.
Given the dynamic route /posts/[id], consider the page /posts/123.
import { useRouter } from 'next/router';
import useSWR from 'swr';
export default function MyPage() {
const router = useRouter();
const { id } = router.query;
const url = `https://my.api.com/posts/${id}` // I've also tried using let here
const { data, error } = useSWR(url, fetcher);
console.log(url)
This URL initially console logs as https://my.api.com/posts/undefined and an error is returned from the API because https://my.api.com/posts/undefined is, of course, not a valid path.
Immediately after, the URL console logs correctly as https://my.api.com/posts/123 and the data on the page usually then populates, but sometimes the data doesn't populate and it's stuck in a 'loading' state. When I hardcode the URL this never happens.
Is there something I'm doing wrong here? Why is the query object not available immediately? Is there a way to elegantly wait for it to be set?
You could try to use conditional data fetching like so:
const { data, error } = useSWR(id ? url : null, id ? fetcher : null);
Also check following conversation: https://github.com/vercel/next.js/discussions/15952
I have a form in ReactJS and every time i click the submit button, the data should pass to adonis api.
ReactJs file
async handleSubmit(e) {
e.preventDefault();
console.log(JSON.stringify(this.state));
await axios({
method: 'post',
url: 'http://127.0.0.1:3333/add',
data: JSON.stringify(this.state),
})
.then(function (response) {
console.log('response',response);
})
.catch(function (error) {
console.log('error',error);
});
}
"http://127.0.0.1:3333/add" is Adonis server with a route '/add'
i don't know how to write in Adonis to post state on that route
Can anybody explain me, please?
in controller's function in get value like this
const data = request.only(['data']) then you get data.
other method to get data like this
const alldata = request.all()
this console this result and view how many result you get
and get data from this alldata.data
First, create a simple controller to handle your data which would receive from your handleSubmit() method in ReactJS app.
Use the below command to create a simple controller:
adonis make:controller TestController --type http
Once created, open the TestController file and make an index method and add the followings which are inside the index method.
'use strict'
class TestController{
// define your index method here
index ({ request }) {
const body = request.post() // get all the post data;
console.log(body) //console it to see the passed data
}
}
module.exports = TestController
After that, register your /add route in start/routes.js file.
Route.post('/add', 'TestController.index') // controller name and the method
And finally, hit the Submit button in your ReactJS app, and test it.
Most likely you be getting CORS issues when you send the request
from your ReactJS app to Adonis server, If so you have to proxy the api request to Adonis server.
To do that, open up your package.json file in ReactJS App, and add the below proxy field.
"proxy": "http://127.0.0.1:3333",
My problem is I'm using auth0 as my authentication service, now when a user logs in and is authenticated it gets redirected back to my callback url which then decides where to send the user now my problem is when you get redirected back to your callback url from auth0 there are queryParams in the url string like so..
http://localhost:4200/account/login/callback#access_token="dsadsadsadsa dasdsaa" just as an example but then in a split second the query string is removed and its left at http://localhost:4200 now Im trying to grab the query Params using this method
this.activatedRoute.queryParams.subscribe(params => {
console.log(params);
});
now this should work but the console.log is an empty object every time, I think its because of that url change that happens..
Is there some way I can grab the query params before that removal??
EDIT
Basically what is happening is I'm getting authenticated then I get redirected to
localhost:4200/account/login/callback?acessToken="dasdasdaefssves"
but then the route changes to
localhost:4200/account/login/callback
without the query parameters before the activatedRoute function gets a chance to run!
Any help would be appreciated!
Notice your redirect-url is http://localhost:4200/account/login/callback?access_token="dsadsadsadsa dasdsaa"
but angular routes it to localhost:4200/account/callback
NOTE
You don't have that /account/login/callback route defined in angular. But you have /account/callback route instead. Angular tries to resolve the route and redirects its to /account/callback without the queryParams.
Define the route in angular and your issue will be resolved.
I didn't get your complete question but as much as I understand. You want to get query parameter from URL.
To get query parameter from URL You need to do this.
constructor(private activatedRoute: ActivatedRoute){}
This is how you can get all the query params from URL.
this.activatedRoute.queryParamMap
.map((params: Params) => params.params)
.subscribe( (params) => {
if(params && params['access_token']){
console.log(params['access_token']);
}
});