Is there a way to retrieve url parameters passed on pages of project built on GatsbyJS? I'm trying to implement a password reset function on my page using AWS, but they can only send the parameters through a link sent to the user's email.
So the flow would be like this :
User triggers Forgot Password -> AWS sends email to user with link -> Link directs to my page with the parameters -> Reset password form automatically populates fields with the parameters passed
Update
Here's my App.js code :
import { Router } from "@reach/router"
const App = () => (
<Layout>
<Router>
<Login path="signin" exact component={Login} />
<Resources path="api/resources" exact component={Resources} />
<Verify path="verify" exact component={Verify} />
<Forgot path="forgot" exact component={Forgot} />
<Reset path="account/reset/:code" exact component={Reset}/>
</Router>
</Layout>
)
export default App;
Reset.js :
export default class ResetForm extends Component {
constructor(props) {
super(props);
this.state = {
password: "",
confirmPassword: "",
vercode: "",
email: "",
emailValid: false,
passValid: false,
confirmValid: false,
codeValid: false,
formValid: true,
formErrors : {
email: false,
password: false,
confirmPassword: false,
vercode: false,
},
respErrors : {
email: {
isValid : true,
message : ""
},
password: {
isValid : true,
message : ""
},
code : {
isValid : true,
message : ""
}
}
};
}
validateField(field, value) {
let password = this.state.password
let fieldValidationErrors = this.state.formErrors;
let emailValid = this.state.emailValid
let passValid = this.state.passValid
let confirmValid = this.state.confirmValid
let codeValid = this.state.vercode
let fieldValidationMessages = this.state.respErrors;
switch(field){
case 'email' :
emailValid = validator.isEmail(value);
fieldValidationErrors.email = emailValid ? false : true;
fieldValidationMessages.email.isValid = true;
fieldValidationMessages.email.message = "Invalid E-Mail Address";
break;
case 'password' :
passValid = validator.matches(value, RegExp('^(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*])(?=.{8,})'));
fieldValidationMessages.password.message = passValid ? '' : undefined;
if(!validator.matches(value,RegExp('^(?=.*[a-z])(?=.*[A-Z])'))){
fieldValidationMessages.password.message = "At least 1 Upper case character is required";
}
if(!validator.matches(value,RegExp('^(?=.*[!@#$%^&*])'))){
fieldValidationMessages.password.message = "At least 1 Symbol is required";
}
if(!validator.matches(value,RegExp('^(?=.{8,})'))){
fieldValidationMessages.password.message = "Password must have at least 8 characters";
}
fieldValidationErrors.password = passValid ? false : true;
break;
case 'confirmPassword' :
confirmValid = validator.equals(value, password);
fieldValidationErrors.confirmPassword = confirmValid ? false : true;
break;
case 'vercode' :
codeValid = !validator.isEmpty(value);
fieldValidationErrors.vercode = codeValid ? false : true;
break;
default :
break
}
this.setState({
formErrors: fieldValidationErrors,
emailValid: emailValid,
passValid: passValid,
confirmValid: confirmValid,
codeValid: codeValid,
}, this.validateForm())
}
validateForm(){
this.setState({
formValid:
this.state.emailValid && this.state.confirmValid && this.state.codeValid && this.state.passValid
})
}
handleChange = event => {
const name = event.target.id;
const value = event.target.value;
this.setState({
[name]: value
},
() => {
this.validateField(name, value)
}
);
}
handleSubmit = async (event) => {
event.preventDefault()
const state = this.state
await handleReset(state)
.then(async (data) => {
if(data.isValid){
await handleLogin(state)
.then(() => {
navigate('/')
})
.catch(err => console.log(err))
} else {
switch (data.code) {
case CODE_RESET.RESET_EXPIRED:
data.message = "The verification code you have submitted is already expired."
break
case CODE_RESET.RESET_MISMATCH:
data.message = "The verification code you have submitted is invalid."
break
default:
data.message = "Something went wrong."
break;
}
this.setState({
[state.respErrors.code.isValid] : data.isValid,
[state.respErrors.code.message] : data.message
})
}
})
.catch(async(err) => {
console.log(err)
})
}
render() {
if(isLoggedIn()) {
navigate(`/`)
}
return (
<Row className={[formStyles.formContainer, "row"].join(' ')} >
<Col sm={{
size:12
}}
md={{
size: 8,
offset: 2
}}
>
<Form
onSubmit={this.handleSubmit}
>
<h3 style={{
fontWeight: 'bolder'
}}>
Reset Password
</h3>
<FormGroup>
<Label for="email">Email</Label>
<Input
id="email"
autoFocus
type="email"
name="email"
value={this.state.email.value}
onChange={this.handleChange}
className={formStyles.signUp}
valid={this.state.emailValid}
invalid={(this.state.formErrors.email || !this.state.respErrors.email.isValid ) ? true : undefined}
/>
<FormFeedback invalid={this.state.respErrors.email.isValid ? '' : undefined}>
{this.state.respErrors.email.message}
</FormFeedback>
</FormGroup>
<FormGroup>
<Label for="password">New Password</Label>
<Input
id="password"
type="password"
name="password"
value={this.state.password.value}
onChange={this.handleChange}
className={formStyles.signUp}
valid={this.state.passValid }
invalid={this.state.formErrors.password ? true : undefined}
/>
<FormText invalid={this.state.respErrors.password.isValid ? '' : undefined}>
{this.state.respErrors.password.message}
</FormText>
</FormGroup>
<FormGroup>
<Label for="confirmPassword">Confirm Password</Label>
<Input
id="confirmPassword"
type="password"
name="confirmPassword"
value={this.state.confirmPassword.value}
onChange={this.handleChange}
className={formStyles.signUp}
valid={this.state.confirmValid }
invalid={this.state.formErrors.confirmPassword ? true : undefined}
/>
<FormFeedback
invalid={this.state.formErrors.confirmPassword ? '' : undefined}
>
Password does not match
</FormFeedback>
</FormGroup>
<FormGroup>
<Label for="vercode">Verification Code</Label>
<Input
id="vercode"
type="text"
name="vercode"
maxLength={6}
value={this.state.vercode.value}
onChange={this.handleChange}
className={formStyles.signUp}
valid={this.state.codeValid.value }
invalid={this.state.formErrors.vercode || !this.state.respErrors.code.isValid ? true : undefined}
/>
<FormFeedback invalid={this.state.respErrors.code.isValid ? '' : undefined} >
{this.state.respErrors.code.message}
</FormFeedback>
</FormGroup>
<Button
color="primary"
disabled={!this.state.formValid}
>
Submit
</Button>
</Form>
</Col>
</Row>
)
}
}
Use props.location
, introduced in Gatsby v2. It's made available by @reach/router to all components via props
.
function Component(props) {
// use props.location...
return ...
}