jekyll-and-hire

jekyll-and-hire

A modern, interactive portfolio website built with Jekyll, featuring a sleek tech-themed design perfect for developers and tech professionals (or anyone interested!). The idea is to, well, get hired!

๐Ÿงช Jekyll & Hire

A modern, interactive portfolio website built with Jekyll, featuring a sleek tech-themed design perfect for developers and tech professionals (or anyone interested!). The idea is to, well, get hired!

๐Ÿ“‹ Table of Contents

๐Ÿš€ Getting Started

๐Ÿ“ง Contact Form Setup

๐ŸŽจ Customization

๐Ÿ”ง Maintenance & Advanced


๐Ÿš€ Getting Started

Overview

A responsive, professional portfolio website template with modern animations and interactive elements. Completely free to use and deploy

โœจ Key Features

  • ๐ŸŽจ Dual Theme System - Professional dark mode + clean light mode
  • ๐Ÿ“ฑ Fully Responsive - Works on all devices
  • โšก Interactive Elements - Custom cursor, parallax effects, smooth animations
  • ๐Ÿ”ง Easy Content Management - Update everything through a single YAML file
  • ๐Ÿš€ Fast Loading - Optimized static site
  • ๐Ÿ” SEO Optimized - Built-in meta tags and structured data
  • ๐Ÿ› ๏ธ GitHub Pages Ready - Deploy with zero configuration
  • ๐Ÿ“ง Functional Contact Form - Google Forms backend with email notifications
  • ๐Ÿ’ฐ 100% Free - No hosting costs, runs on GitHub Pages

๐ŸŽฏ Perfect For

  • Anyone looking for a modern portfolio!

๐Ÿš€ How to Use

Prerequisites

Before you begin, make sure you have:

  • Ruby (version 3.0 or higher) - Download here (Windows) or brew install ruby (macOS)
  • Bundler - Install with gem install bundler
  • Git - Download here

Local Development Setup

  1. Clone the repository

    git clone https://github.com/yourusername/your-portfolio.git
    cd your-portfolio
    
  2. Install dependencies

    bundle install
    
  3. Start the development server

    bundle exec jekyll serve
    
  4. Open your browser

    Visit: http://localhost:4000
    

Your site will automatically reload when you make changes!

๐Ÿ“ง Contact Form Setup

Contact Form Backend Setup

Your portfolio includes a fully functional contact form with Google Forms backend, email notifications, and spam protection. Here's how to set it up:

๐Ÿš€ Quick Setup Overview (5 minutes)

  1. Create Google Form โ†’ Get form submissions
  2. Connect Google Sheet โ†’ Store responses automatically
  3. Deploy Apps Script โ†’ Send custom email notifications
  4. Update JavaScript โ†’ Connect your frontend to backend

Step 1: Create Google Form (2 minutes)

  1. Go to forms.google.com

  2. Click "Blank Form"

  3. Set form title: "Portfolio Contact Form"

  4. Add these EXACT fields:

    Question 1: Name
    - Type: Short answer
    - Required: YES
    
    Question 2: Email  
    - Type: Short answer
    - Required: YES
    
    Question 3: Subject
    - Type: Short answer
    - Required: YES
    
    Question 4: Message
    - Type: Paragraph
    - Required: YES
    

Step 2: Connect Google Sheet (30 seconds)

  1. In your Google Form, click the Responses tab
  2. Click the green Google Sheets icon ๐Ÿ“Š
  3. Select "Create a new spreadsheet"
  4. Name it: "Portfolio Contact Responses"
  5. Click "Create" โ†’ Google automatically links them

Step 3: Deploy Google Apps Script (2 minutes)

  1. Open your new Google Sheet
  2. Click Extensions โ†’ Apps Script
  3. Replace the default code with this enhanced script:
// =====================================================================================
// PORTFOLIO CONTACT FORM - Google Apps Script Email Notifications
// =====================================================================================

const CONFIG = {
  YOUR_EMAIL: '[email protected]', // ๐Ÿ”ฅ UPDATE THIS!
  SEND_AUTO_RESPONDER: true,
  EMAIL_SIGNATURE: 'Your Name' // ๐Ÿ”ฅ UPDATE THIS!
};

function onFormSubmit(e) {
  try {
    const values = e.values;
    const [timestamp, name, email, subject, message] = values;
    
    // Send notification to you
    sendNotificationEmail({ timestamp, name, email, subject, message });
    
    // Send confirmation to form submitter
    if (CONFIG.SEND_AUTO_RESPONDER) {
      sendAutoResponder({ name, email, subject });
    }
    
    console.log('โœ… Emails sent successfully');
  } catch (error) {
    console.error('โŒ Error:', error);
  }
}

function sendNotificationEmail(data) {
  const subject = `๐Ÿš€ New Portfolio Contact: ${data.subject}`;
  const htmlBody = `
    <div style="font-family: 'Segoe UI', Arial, sans-serif; max-width: 900px; margin: 0 auto; border: 1px solid #e0e0e0; border-radius: 8px;">
      <div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 30px; color: white; text-align: center;">
        <h2 style="margin: 0; font-size: 28px;">๐Ÿš€ New Portfolio Contact</h2>
        <p style="margin: 10px 0 0 0; opacity: 0.9;">Professional inquiry received</p>
      </div>
      
      <div style="background: #f8f9fa; padding: 30px;">
        <div style="background: white; padding: 25px; border-radius: 8px; border-left: 4px solid #667eea;">
          <table style="width: 100%;">
            <tr>
              <td style="width: 50%; padding-right: 20px;">
                <strong>๐Ÿ‘ค Name:</strong> ${data.name}<br>
                <strong>๐Ÿ“ง Email:</strong> <a href="mailto:${data.email}">${data.email}</a>
              </td>
              <td style="width: 50%; border-left: 1px solid #e9ecef; padding-left: 20px;">
                <strong>๐Ÿ“‹ Subject:</strong> ${data.subject}<br>
                <strong>โฐ Time:</strong> ${data.timestamp}
              </td>
            </tr>
          </table>
        </div>
      </div>
      
      <div style="background: white; padding: 30px;">
        <h3 style="margin: 0 0 20px 0; color: #495057;">๐Ÿ’ฌ Message:</h3>
        <div style="background: #f8f9fa; padding: 25px; border-left: 4px solid #28a745; border-radius: 8px;">
          <p style="margin: 0; line-height: 1.7; color: #495057;">${data.message.replace(/\n/g, '<br>')}</p>
        </div>
      </div>
      
      <div style="background: #f8f9fa; padding: 25px; text-align: center;">
        <a href="mailto:${data.email}?subject=Re: ${data.subject}" 
           style="background: #667eea; color: white; padding: 15px 30px; text-decoration: none; border-radius: 6px; font-weight: 600;">
          ๐Ÿ“ง Reply to ${data.name}
        </a>
      </div>
    </div>
  `;
  
  MailApp.sendEmail({
    to: CONFIG.YOUR_EMAIL,
    subject: subject,
    htmlBody: htmlBody,
    replyTo: data.email
  });
}

function sendAutoResponder(data) {
  const subject = `โœ… Thank you for your message, ${data.name}!`;
  const htmlBody = `
    <div style="font-family: 'Segoe UI', Arial, sans-serif; max-width: 900px; margin: 0 auto; border: 1px solid #e0e0e0; border-radius: 8px;">
      <div style="background: linear-gradient(135deg, #28a745 0%, #20c997 100%); padding: 30px; color: white; text-align: center;">
        <h2 style="margin: 0; font-size: 28px;">โœ… Message Received</h2>
        <p style="margin: 10px 0 0 0; opacity: 0.9;">Thank you for reaching out!</p>
      </div>
      
      <div style="background: white; padding: 40px;">
        <p style="font-size: 18px; margin: 0 0 20px 0;"><strong>Hello ${data.name},</strong></p>
        
        <p style="margin: 0 0 25px 0; line-height: 1.7; color: #6c757d;">
          Thank you for reaching out through my portfolio! I've received your message regarding 
          "<strong>${data.subject}</strong>" and appreciate you taking the time to connect.
        </p>
        
        <div style="background: #f8f9fa; padding: 25px; border-left: 4px solid #28a745; margin: 25px 0; text-align: center;">
          <p style="margin: 0; font-weight: 500;"><span style="color: #28a745;">โšก</span> I'll respond within 24 hours</p>
        </div>
        
        <p style="margin: 0; line-height: 1.7; color: #6c757d;">
          Best regards,<br>
          <strong>${CONFIG.EMAIL_SIGNATURE}</strong><br>
          <span style="color: #adb5bd;">Portfolio & Professional Services</span>
        </p>
      </div>
    </div>
  `;
  
  MailApp.sendEmail({
    to: data.email,
    subject: subject,
    htmlBody: htmlBody,
    replyTo: CONFIG.YOUR_EMAIL
  });
}

// Test function - run this to test email notifications
function testEmails() {
  const testData = {
    timestamp: new Date().toLocaleString(),
    name: "Test Contact",
    email: CONFIG.YOUR_EMAIL,
    subject: "System Test",
    message: "This is a test message to verify the email system works correctly."
  };
  
  sendNotificationEmail(testData);
  sendAutoResponder(testData);
  console.log('โœ… Test emails sent!');
}
  1. Update the CONFIG section:

    const CONFIG = {
      YOUR_EMAIL: '[email protected]', // Your actual email
      SEND_AUTO_RESPONDER: true,
      EMAIL_SIGNATURE: 'Your Name' // Your actual name
    };
    
  2. Save the project (Ctrl+S or File โ†’ Save)


Step 4: Set Up the Trigger (30 seconds)

  1. In Apps Script, click the Triggers icon โฐ (left sidebar)
  2. Click "Add Trigger"
  3. Configure:
    • Function: onFormSubmit
    • Event source: From spreadsheet
    • Event type: On form submit
  4. Click "Save" and authorize permissions when prompted

Step 5: Get Form IDs for Frontend (1 minute)

  1. Get Form ID:

    • In Google Form, click "Send" button
    • Click the link icon ๐Ÿ”—
    • Copy the ID from URL: https://docs.google.com/forms/d/FORM_ID_HERE/viewform
  2. Get Entry IDs:

    • Right-click on form โ†’ View Page Source and look for the 4 different form boxes (e.g, Name, Email, Subject, Message)
    • Search for the field name (Ctrl+F) and look for them in one of the elements
      • Only look for the word (e.g., Message) and search within the [[ character space. This is where the form id is located (e.g., 000000000)
    • Copy the 4 entry IDs you find as in this example:
      <div jsmodel="CP1oW" data-params="%.@.[1234567890,&quot;Message&quot;,null,0,[[000000000,null,true,null,null,null,null,null,null,null,[]]],null,null,null,null,null,null,[null,&quot;Message&quot;]]  <!-- Message field -->
      

Step 6: Update Your JavaScript (30 seconds)

In your assets/js/main.js, update the configuration:

const CONTACT_FORM_CONFIG = {
    formId: 'YOUR_ACTUAL_FORM_ID_HERE', // From Step 5
    fields: {
        name: 'entry.YOUR_NAME_ENTRY_ID',     // From Step 5
        email: 'entry.YOUR_EMAIL_ENTRY_ID',    // From Step 5  
        subject: 'entry.YOUR_SUBJECT_ENTRY_ID', // From Step 5
        message: 'entry.YOUR_MESSAGE_ENTRY_ID'  // From Step 5
    },
    fallbackEmail: '[email protected]' // Your email
};

Testing Your Setup

  1. Test the Apps Script:

    • In Apps Script, run the testEmails() function
    • Check your email for test notifications
  2. Test the Live Form:

    • Submit a test message through your portfolio
    • Verify you receive both emails (notification + auto-responder)
    • Check Google Sheet for the response data
  3. Troubleshooting:

    • Check browser console for JavaScript errors
    • Verify form IDs and entry IDs are correct
    • Ensure trigger is properly set up
    • Check spam folder for emails

โœจ Contact Form Benefits

โœ… Spam protection via Google Forms
โœ… Custom HTML email notifications
โœ… Auto-responder for form submitters
โœ… Automatic data storage in Google Sheets
โœ… Mobile-friendly emails
โœ… Easy maintenance through Google's interface
โœ… 100% free - no hosting costs

Setup Time: ~5 minutes | Maintenance: Zero


๐ŸŽจ Customization

Customizing the Portfolio YAML file

All your content is managed through two main files:

๐ŸŽฏ Primary Content

File: _data/portfolio.yml

This YAML file contains all your personal information, experience, and projects. Here's how to edit each section:

๐Ÿ‘ค Personal Information:

personal:
  name: "Your Full Name"                    # Appears in hero section
  title: "Your Professional Title"          # Job title/role
  tagline: "// Your Personal Motto"         # Appears under title
  logo: "Y.N"                               # Your initials for navigation
  email: "[email protected]"           # Contact email
  phone: "+1 (555) 123-4567"                # Phone number
  location: "Your City, State"              # Where you're located
  linkedin: "linkedin.com/in/yourprofile"   # LinkedIn profile
  github: "github.com/yourusername"         # GitHub profile
  profileImage: "/assets/img/profile.jpg"   # Path to your photo
  bio:                                      # About section paragraphs
    - "First paragraph about your background..."
    - "Second paragraph about your interests..."
    - "Third paragraph about your philosophy..."

๐Ÿ’ผ Professional Experience:

experience:
  - title: "Your Job Title"                 # Position name
    company: "Company Name"                 # Employer
    period: "2022 - Present"                # Employment dates
    description: "What you accomplished in this role..."

๐ŸŽ“ Education:

education:
  - degree: "Bachelor of Computer Science"  # Degree name
    institution: "University Name"          # School name
    period: "2016 - 2020"                   # Dates attended
    description: "Relevant coursework, honors, etc."

๐Ÿ† Certifications:

certifications:
  - name: "AWS Certified"                   # Certification name
    issuer: "Amazon Web Services"           # Issuing organization
    year: "2023"                            # Year obtained

๐Ÿ’ป Skills:

skills:
  - category: "Programming"                 # E.g., "Programming Languages"
    icon: "โšก"                              # Emoji icon for visual appeal
    tags:                                   # List of specific skills
      - "Python"
      - "JavaScript"
      - "React"

๐Ÿš€ Projects:

projects:
  - title: "Project Name"                   # Project title
    icon: "๐Ÿค–"                             # Emoji icon
    description: "Brief description of what this project does..."
    links:                                 # Project links
      - label: "Demo"                      # Link text
        url: "https://demo-link.com"       # Actual URL
      - label: "GitHub"
        url: "https://github.com/user/repo"

๐Ÿงญ Navigation:

navigation:
  - label: "HOME"
    href: "#home"
  - label: "ABOUT"
    href: "#about"
  - label: "SKILLS"
    href: "#skills"

๐Ÿ” SEO Settings:

seo:
  title: "Your Name - Your Title"
  description: "Brief description for search engines..."
  keywords: "your, skills, here"
  ogImage: "/assets/img/og-image.jpg"

Customing the Site Configuration YAML File

File: _config.yml

title: "Your Portfolio Title"
description: "Your professional description"
url: "https://yourusername.github.io"
baseurl: "/repository-name"

author: "Your Name"
google_analytics: "GA_MEASUREMENT_ID"  # Optional

YAML Editing Tips

Important rules:

  • Use spaces, not tabs for indentation
  • Keep consistent spacing (2 spaces per level)
  • Quote strings with special characters
  • Use lists with - for multiple items

Example:

skills:
  - category: "Programming"
    icon: "โšก"
    tags:
      - "Python"
      - "JavaScript"

Validation:

ruby -c _data/portfolio.yml

Or use online: yamllint.com

Profile Image

Add your photo to assets/img/profile.jpg

  • Recommended: 500x500px, JPG format, under 500KB

Deployment

GitHub Pages (Free)

  1. Push code to GitHub
  2. Go to repository Settings โ†’ Pages
  3. Under Build and deployment select Source: "GitHub Actions"
  4. Click on Configure for GitHub Pages Jekyll
  5. Press on Commit changes on both windows
  6. Visit your your site once deployment is completed: https://yourusername.github.io/repository-name

๐Ÿ”ง Maintenance & Advanced

Content Workflow

Update your portfolio in 4 steps:

  1. Edit content: _data/portfolio.yml
  2. Test locally: bundle exec jekyll serve
  3. Deploy: git add . && git commit -m "Update content" && git push
  4. Wait 2-5 minutes for GitHub Pages to rebuild

Important Files

Files you'll edit regularly:

  • _data/portfolio.yml - Your content
  • _config.yml - Site settings
  • assets/img/profile.jpg - Your profile photo

Files to leave alone:

  • _layouts/default.html - Site structure
  • assets/css/style.css - All styling
  • assets/js/main.js - Interactive features
  • index.html - Homepage template

Quick Setup Checklist

After cloning, customize these in order:

Troubleshooting

Common issues and solutions:

Problem Solution
Site not building Check bundle exec jekyll build --verbose for errors
Content not updating Ensure YAML syntax is correct (spaces, not tabs)
YAML parsing errors Use yamllint.com to validate
Contact form not working Follow the Contact Form Backend Setup section
Images not loading Verify file paths and image file names

YAML syntax check:

ruby -c _data/portfolio.yml

๐ŸŽฏ Customization

๐ŸŽจ Change Colors

Edit assets/css/style.css:

:root {
  --primary-cyber: #your-color;
  --secondary-cyber: #your-color;
}

๐Ÿ“Š Add Analytics

Add to _config.yml:

google_analytics: "GA_MEASUREMENT_ID"

โญ If this template helped you, consider starring this repository!

jekyll logo

Want a Jekyll website built?

Hire a Jekyll developer