Here is the final, complete index.php file.
This version includes:
* PHP Email Handler (Top): Detects if the form was sent, sends the email, and quits before loading the HTML (so the page doesn’t reload).
* HTML5 History: The Back/Forward buttons work.
* AJAX Form: The contact form sends the email in the background without refreshing.
You can overwrite your previous file with this one.
The Complete index.php
<?php
// — 1. PHP EMAIL HANDLER (Must be at the very top) —
if ($_SERVER[“REQUEST_METHOD”] == “POST”) {
// CONFIGURATION
$to = “your-email@example.com”; // <— CHANGE THIS TO YOUR EMAIL
$subject = “New Contact Form Message”;
// Sanitize inputs
$email = filter_var($_POST[’email’], FILTER_SANITIZE_EMAIL);
$message = htmlspecialchars($_POST[‘message’]);
$headers = “From: ” . $email . “\r\n”;
$headers .= “Reply-To: ” . $email . “\r\n”;
// Attempt to send
if(mail($to, $subject, $message, $headers)) {
echo “Success”; // Send ‘Success’ back to Javascript
} else {
echo “Error: Server could not send mail.”;
}
// STOP the script here so we don’t reload the HTML
exit;
}
// — 2. REGULAR PAGE CONFIGURATION —
$siteTitle = “Instant SPA Site”;
$pages = [
‘home’ => ‘Home’,
‘about’ => ‘About Us’,
‘services’ => ‘Services’,
‘contact’ => ‘Contact’
];
?>
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<meta name=”viewport” content=”width=device-width, initial-scale=1.0″>
<title><?php echo $siteTitle; ?></title>
<style>
body { font-family: ‘Segoe UI’, sans-serif; margin: 0; padding: 0; background: #f0f2f5; color: #333; }
/* Navigation */
nav { background: #2c3e50; padding: 1rem 2rem; position: sticky; top: 0; z-index: 100; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
nav ul { list-style: none; padding: 0; margin: 0; display: flex; gap: 25px; }
nav a { color: #ecf0f1; text-decoration: none; font-weight: 600; font-size: 1.1rem; transition: color 0.2s; }
nav a:hover { color: #3498db; }
nav a.active { color: #3498db; border-bottom: 2px solid #3498db; padding-bottom: 2px; }
/* Container */
.container { max-width: 800px; margin: 3rem auto; background: white; padding: 3rem; border-radius: 12px; box-shadow: 0 4px 15px rgba(0,0,0,0.05); }
/* Content Visibility & Animation */
.page-section { display: none; }
.page-section.active { display: block; animation: fadeEffect 0.4s; }
@keyframes fadeEffect {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
h1 { margin-top: 0; border-bottom: 1px solid #eee; padding-bottom: 15px; }
/* Form Styles */
.form-group { margin-bottom: 15px; }
label { display: block; margin-bottom: 5px; font-weight: bold; }
input, textarea { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 4px; box-sizing: border-box; }
button[type=”submit”] { padding: 10px 20px; background: #3498db; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 1rem; }
button[type=”submit”]:hover { background: #2980b9; }
#form-message { margin-top: 15px; font-weight: bold; }
</style>
</head>
<body>
<nav>
<ul>
<?php foreach($pages as $id => $label): ?>
<li>
<a href=”#<?php echo $id; ?>” class=”nav-link” data-target=”<?php echo $id; ?>”>
<?php echo $label; ?>
</a>
</li>
<?php endforeach; ?>
</ul>
</nav>
<div class=”container”>
<div id=”home” class=”page-section”>
<h1>Welcome Home</h1>
<p>This is a single-file PHP website.</p>
<p>Navigate using the links above. Notice the page never flashes or reloads.</p>
</div>
<div id=”about” class=”page-section”>
<h1>About Us</h1>
<p>We specialize in lightweight web solutions.</p>
</div>
<div id=”services” class=”page-section”>
<h1>Services</h1>
<ul>
<li>PHP Backend</li>
<li>jQuery Frontend</li>
<li>AJAX Forms</li>
</ul>
</div>
<div id=”contact” class=”page-section”>
<h1>Contact Us</h1>
<form id=”ajax-contact-form”>
<div class=”form-group”>
<label>Your Email:</label>
<input type=”email” name=”email” required placeholder=”name@example.com”>
</div>
<div class=”form-group”>
<label>Message:</label>
<textarea name=”message” rows=”5″ required placeholder=”How can we help?”></textarea>
</div>
<button type=”submit” id=”submit-btn”>Send Message</button>
<div id=”form-message”></div>
</form>
</div>
</div>
https://code.jquery.com/jquery-3.6.0.min.js
<script>
$(document).ready(function() {
// — 1. PAGE SWITCHING LOGIC —
function switchPage(pageId) {
// Hide all, Show target
$(‘.page-section’).removeClass(‘active’);
$(‘#’ + pageId).addClass(‘active’);
// Update Nav
$(‘.nav-link’).removeClass(‘active’);
$(‘.nav-link[data-target=”‘ + pageId + ‘”]’).addClass(‘active’);
// Update Browser Tab Title
var pageTitle = $(‘.nav-link[data-target=”‘ + pageId + ‘”]’).text().trim();
document.title = pageTitle + ” | ” + “<?php echo $siteTitle; ?>”;
}
// — 2. NAVIGATION CLICKS —
$(‘.nav-link’).click(function(e) {
e.preventDefault();
var targetPage = $(this).data(‘target’);
if (!$(this).hasClass(‘active’)) {
history.pushState(null, null, ‘#’ + targetPage);
switchPage(targetPage);
}
});
// — 3. BROWSER HISTORY (BACK BUTTON) —
$(window).on(‘popstate’, function() {
var hash = window.location.hash.replace(‘#’, ”);
switchPage(hash ? hash : ‘home’);
});
// — 4. INITIAL LOAD —
var initialHash = window.location.hash.replace(‘#’, ”);
switchPage(initialHash ? initialHash : ‘home’);
// — 5. AJAX FORM SUBMISSION —
$(‘#ajax-contact-form’).submit(function(e) {
e.preventDefault(); // Stop normal reload
var $btn = $(‘#submit-btn’);
var $msg = $(‘#form-message’);
var originalText = $btn.text();
// Show loading state
$btn.text(‘Sending…’).prop(‘disabled’, true);
$msg.text(”);
// Send data to this same file (index.php)
$.post(‘index.php’, $(this).serialize(), function(response) {
if (response.trim() === “Success”) {
$msg.css(‘color’, ‘green’).text(‘Message sent successfully!’);
$(‘#ajax-contact-form’)[0].reset(); // Clear inputs
} else {
$msg.css(‘color’, ‘red’).text(response); // Show error
}
}).fail(function() {
$msg.css(‘color’, ‘red’).text(‘Connection error. Please try again.’);
}).always(function() {
// Reset button
$btn.text(originalText).prop(‘disabled’, false);
});
});
});
</script>
</body>
</html>
Important Note on Testing
If you are running this on your local computer (localhost/XAMPP):
The mail() function usually does not work on localhost out of the box because your computer isn’t an email server. You will see the “Error: Server could not send mail” message.
However, once you upload this to a real web host (or if you configure your local php.ini with SMTP settings), it will work immediately.
Next Step:
Now that you have a functioning backend, would you like me to show you how to add a simple “Password Protection” check at the top of this same file, so only you can access the site while you are building it?
Discover more from NathanLegakis.com
Subscribe to get the latest posts sent to your email.
Leave a comment