Skip to content

Personal Website - Contact

The contact page has a form where visitors can leave their name, email, and a message. When they click Send, the details go to your Flask backend without the page reloading.

You have done exactly this kind of thing before - sending form data to Flask using fetch. If you need a reminder of how it works, see Create - Sending Data.


contact.html

{% extends "base.html" %}

{% block content %}
  <h1>Contact Me</h1>

  <p>Fill in the form below and I will get back to you.</p>

  <div>
    <input id="name"    type="text"  class="form-control mb-2" placeholder="Your name">
    <input id="email"   type="email" class="form-control mb-2" placeholder="Your email">
    <textarea id="message" class="form-control mb-2" rows="4" placeholder="Your message"></textarea>
    <button onclick="sendMessage()" class="btn btn-primary">Send</button>
  </div>

  <p id="status" style="display:none; color:green; margin-top:12px;">Message sent!</p>

  <script>
    function sendMessage() {
      let name    = document.getElementById("name").value
      let email   = document.getElementById("email").value
      let message = document.getElementById("message").value

      fetch("/contact", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ name: name, email: email, message: message })
      })
        .then(response => response.json())
        .then(result => {
          document.getElementById("name").value    = ""
          document.getElementById("email").value   = ""
          document.getElementById("message").value = ""
          document.getElementById("status").style.display = "block"
        })
        .catch(error => console.log("Error:", error))
    }
  </script>
{% endblock %}

form-control on each input and btn btn-primary on the button - both classes you already know. On success the form clears and the hidden <p> becomes visible.


The Flask route

Add this to app.py:

from flask import Flask, render_template, request, jsonify

@app.route('/contact', methods=['POST'])
def handle_contact():
    data = request.get_json()
    print("Name:",    data["name"])
    print("Email:",   data["email"])
    print("Message:", data["message"])
    return jsonify({ "status": "ok" })

For now the route just prints the details to your terminal. In a real site you would email them to yourself or save them to a database. The important thing is: it receives the data and responds.


Challenge

Run the app. Fill in the contact form and click Send. Check your terminal - you should see the name, email, and message printed there. The form should clear and "Message sent!" should appear on the page.


← Personal Website - About    Next: Challenge - Student Registration →