0

I have a form component where user fills out the inputs, hits send and then is redirected to the success page. But if anyone who would like to enter url manually like domain.com/success, he will see that page. How can I disable this? For example, if enters domain.com/success, then redirects to /home. Here is my code:

import React, { useState } from "react"

const ContactForm = () => {
  const [formInput, setFormInput] = useState({
    email: "",
    message: "",
  })

  const onChange = e => {
    setFormInput({
      ...formInput,
      [e.target.name]: e.target.value,
    })
  }

  return (
    <section className="contact-form" id="contact">
      <h1>Contact Us</h1>
      <div className="container">
        <form
          method="post"
          netlify-honeypot="bot-field"
          data-netlify="true"
          name="contact"
          action="/success"
        >
          <input type="hidden" name="form-name" value="contact" />
          <div className="form-group">
            <div className="form-input">
              <input
                type="email"
                className="form-control"
                id="exampleFormControlInput1"
                placeholder="Your email"
                name="email"
                required
                value={formInput.name}
                onChange={onChange}
              ></input>
            </div>
          </div>
          <div className="form-group">
            <div className="form-input">
              <textarea
                className="form-control"
                id="exampleFormControlTextarea1"
                rows="3"
                placeholder="Your message"
                name="message"
                required
                value={formInput.message}
                onChange={onChange}
              ></textarea>
            </div>
          </div>

          <button type="submit" className="button button--lg">
            Send
          </button>
        </form>
      </div>
    </section>
  )
}

export default ContactForm
istoby
  • 155
  • 1
  • 7
  • Have you seen this [question](https://stackoverflow.com/questions/39288915/detect-previous-path-in-react-router)? – Tejogol Oct 05 '20 at 12:15

1 Answers1

0

Gatsby has an API hook called onInitialClientRender that will be called on the initial render (i.e. when a full page load occurs) but not subsequent renders (when navigating client-side). To use it, you export a function from gatsby-browser.js with that name. You could use this function to check that window.location.pathname doesn't match that route, and if it does, call navigate with a new location to redirect the user.

import { navigate } from "gatsby"

export const onInitialClientRender = () => {
  if (window.location.pathname.startsWith("/success/")) {
    navigate("/")
  }
}

Another way you could go about this is to only render the success page client-side. Here's the documentation for this process.

coreyward
  • 77,547
  • 20
  • 137
  • 166
  • Now when I load the page and try to get to /success page, it enters it and leaves instantly. Also, when I try to send a test email from the form, it shows the success page and instantly redirects to /. Am I doing something wrong? – istoby Oct 06 '20 at 08:30
  • @istoby The brief load and redirect is expected. The alternative is using server-side redirects, which is out of the purview of Gatsby. How are you navigating to the /success page from your form? Are you using `navigate` (recommended) or are you prompting a new page load? – coreyward Oct 06 '20 at 16:44
  • I have atribute "action" with property "/success" in the form tag. – istoby Oct 06 '20 at 19:13
  • @istoby You need to handle the form submission client-side (i.e. pass a callback function to the `onSubmit` prop, do `event.preventDefault()`, submit the form, and then use `navigate` to redirect. Or you can just use state to show the success inline. – coreyward Oct 06 '20 at 20:49
  • Missing bracket. Should be `(window.location.pathname.startsWith("/success/"))` – Neil Morgan Dec 30 '20 at 22:52