TypeScript Tutorial: Building a Simple Web-Based Portfolio

In today’s digital age, a personal portfolio website is more than just a nice-to-have; it’s a necessity. It’s your digital storefront, a place to showcase your skills, projects, and experiences to potential employers or clients. Building one, however, can seem daunting, especially if you’re new to web development. This tutorial will guide you through creating a simple, yet effective, web-based portfolio using TypeScript. We’ll break down the process step-by-step, making it easy for beginners to understand and build their own professional online presence.

Why TypeScript?

You might be wondering why we’re choosing TypeScript over plain JavaScript for this project. TypeScript offers several advantages, especially for larger projects, and it’s a great tool to learn. Here’s why:

  • Type Safety: TypeScript adds static typing to JavaScript. This means you can define the types of variables, function parameters, and return values. The TypeScript compiler will catch type errors during development, helping you avoid runtime errors.
  • Improved Code Maintainability: With types, your code becomes more readable and easier to understand. This is especially helpful when working on a project with a team or when revisiting your code after a long break.
  • Enhanced Developer Experience: TypeScript provides better autocompletion, refactoring, and other IDE features, making development more efficient.
  • Modern JavaScript Features: TypeScript supports the latest JavaScript features, allowing you to write cleaner and more concise code.

Setting Up the Project

Before we dive into the code, let’s set up our project environment. We’ll be using Node.js and npm (Node Package Manager) for this tutorial. If you don’t have them installed, download and install them from the official Node.js website. Open your terminal or command prompt and follow these steps:

  1. Create a Project Directory: Create a new directory for your project and navigate into it.
mkdir my-portfolio
cd my-portfolio
  1. Initialize npm: Initialize a new npm project. This will create a package.json file, which manages your project’s dependencies and scripts.
npm init -y
  1. Install TypeScript: Install TypeScript globally or locally (we’ll install it locally for this project).
npm install typescript --save-dev
  1. Create a TypeScript Configuration File: Create a tsconfig.json file to configure the TypeScript compiler. You can generate a basic one using the following command:
npx tsc --init

This command creates a tsconfig.json file with default settings. You can customize these settings to fit your project’s needs. For our portfolio, the default settings will work fine. Your project structure should now look something like this:

my-portfolio/
├── node_modules/
├── package.json
├── package-lock.json
└── tsconfig.json

Project Structure and Core Components

Let’s plan the structure of our portfolio. We’ll keep it simple to focus on the TypeScript aspects. We’ll need the following components:

  • HTML File (index.html): This will be the main entry point of our portfolio.
  • TypeScript Files (e.g., app.ts, components/*.ts): These files will contain our TypeScript code, which will handle the logic and interactions of our portfolio.
  • CSS File (style.css): This will contain the styling for our portfolio. (We’ll keep this very basic for now.)

Here’s a suggested folder structure:

my-portfolio/
├── src/
│   ├── components/
│   │   ├── about.ts
│   │   ├── projects.ts
│   │   └── contact.ts
│   ├── app.ts
│   └── style.css
├── index.html
├── node_modules/
├── package.json
├── package-lock.json
└── tsconfig.json

Writing the HTML (index.html)

Create an index.html file in the root directory of your project. This file will contain the basic structure of your portfolio. Here’s a simple example:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My Portfolio</title>
    <link rel="stylesheet" href="src/style.css">
</head>
<body>
    <header>
        <h1>Your Name</h1>
        <p>Software Engineer</p>
    </header>
    <main>
        <section id="about">
            <h2>About Me</h2>
            <p>Write a brief introduction about yourself.</p>
        </section>
        <section id="projects">
            <h2>Projects</h2>
            <!-- Projects will be displayed here -->
        </section>
        <section id="contact">
            <h2>Contact</h2>
            <p>Contact information will go here.</p>
        </section>
    </main>
    <script src="app.js"></script>
</body>
</html>

This HTML provides the basic structure. We’ll fill in the content dynamically with TypeScript later.

Writing the TypeScript (app.ts)

Create a file named app.ts inside the src directory. This is where we’ll write the main logic of our portfolio. Let’s start with a simple example that displays a welcome message.

// src/app.ts

function displayWelcomeMessage(name: string): void {
  const header = document.querySelector('header');
  if (header) {
    const welcomeMessage = document.createElement('p');
    welcomeMessage.textContent = `Welcome, ${name}!`;
    header.appendChild(welcomeMessage);
  }
}

// Example usage:
displayWelcomeMessage('Your Name');

In this code:

  • We define a function displayWelcomeMessage that takes a name (a string) as input.
  • Inside the function, we find the header element in our HTML.
  • We create a new p element to display the welcome message.
  • We set the text content of the p element using template literals.
  • Finally, we append the p element to the header.
  • We call the function with your name to display the welcome message.

Important: To make this code work, you need to compile the TypeScript code into JavaScript and link it in your HTML file. We’ll do this in the next steps.

Compiling TypeScript

To compile your TypeScript code into JavaScript, you can use the TypeScript compiler (tsc). In your terminal, navigate to your project directory and run the following command:

npx tsc

This command will compile all .ts files in your src directory and create corresponding .js files in the same directory. For example, app.ts will be compiled into app.js.

Common Mistakes:

  • Incorrect File Paths: Make sure the paths in your index.html (e.g., <script src="app.js">) are correct relative to your HTML file.
  • Missing TypeScript Compilation: If you don’t run tsc, your TypeScript code won’t be converted to JavaScript, and your code won’t work in the browser.

Adding CSS (style.css)

Create a style.css file inside the src directory. Add some basic styling to make your portfolio look presentable. Here’s a simple example:

/* src/style.css */
body {
    font-family: sans-serif;
    margin: 0;
    padding: 0;
    background-color: #f4f4f4;
    color: #333;
    line-height: 1.6;
}

header {
    background-color: #333;
    color: #fff;
    padding: 1rem 0;
    text-align: center;
}

main {
    padding: 20px;
}

section {
    margin-bottom: 20px;
    padding: 15px;
    background-color: #fff;
    border-radius: 8px;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}

This CSS provides basic styling for the body, header, and sections. Feel free to customize it to match your preferences.

Creating Components: About Me

Let’s create components for the different sections of our portfolio. First, we’ll create an “About Me” component. Create a file named about.ts inside the src/components directory. This component will be responsible for displaying information about you.

// src/components/about.ts

export function renderAboutSection(): void {
  const aboutSection = document.getElementById('about');

  if (aboutSection) {
    aboutSection.innerHTML = `
      <h2>About Me</h2>
      <p>Your introduction goes here.  Talk about your skills, experience, and what you're passionate about.</p>
      <p>You can also include a photo or a link to your resume.</p>
    `;
  }
}

In this code:

  • We define a function renderAboutSection.
  • We get the aboutSection element from the HTML using its ID.
  • If the element exists, we set its innerHTML to display the content of the “About Me” section.

Creating Components: Projects

Next, we create a “Projects” component. Create a file named projects.ts inside the src/components directory.

// src/components/projects.ts

interface Project {
  name: string;
  description: string;
  imageUrl: string;
  link: string;
}

export function renderProjectsSection(projects: Project[]): void {
  const projectsSection = document.getElementById('projects');

  if (projectsSection) {
    let projectsHTML = '<h2>Projects</h2>';

    projects.forEach(project => {
      projectsHTML += `
        <div class="project">
          <img src="${project.imageUrl}" alt="${project.name}">
          <h3>${project.name}</h3>
          <p>${project.description}</p>
          <a href="${project.link}" target="_blank">View Project</a>
        </div>
      `;
    });

    projectsSection.innerHTML = projectsHTML;
  }
}

In this code:

  • We define an interface Project to represent a project with properties like name, description, image URL, and link.
  • We define a function renderProjectsSection that takes an array of Project objects as input.
  • We get the projectsSection element from the HTML.
  • We iterate through the projects array and create HTML for each project.
  • We set the innerHTML of the projectsSection to display the projects.

Creating Components: Contact

Finally, we’ll create a “Contact” component. Create a file named contact.ts inside the src/components directory.

// src/components/contact.ts

export function renderContactSection(): void {
  const contactSection = document.getElementById('contact');

  if (contactSection) {
    contactSection.innerHTML = `
      <h2>Contact</h2>
      <p>Email: your.email@example.com</p>
      <p>LinkedIn: <a href="your_linkedin_profile" target="_blank">Your LinkedIn</a></p>
    `;
  }
}

This component displays your contact information. Replace the placeholder values with your actual contact details.

Integrating the Components in app.ts

Now, let’s integrate these components into app.ts. We’ll import the functions from the component files and call them to render the sections.

// src/app.ts
import { renderAboutSection } from './components/about';
import { renderProjectsSection } from './components/projects';
import { renderContactSection } from './components/contact';

// Define your projects data
const projects = [
  {
    name: 'Project 1',
    description: 'A brief description of project 1.',
    imageUrl: 'path/to/project1-image.jpg',
    link: 'https://example.com/project1',
  },
  {
    name: 'Project 2',
    description: 'A brief description of project 2.',
    imageUrl: 'path/to/project2-image.jpg',
    link: 'https://example.com/project2',
  },
];

function displayWelcomeMessage(name: string): void {
  const header = document.querySelector('header');
  if (header) {
    const welcomeMessage = document.createElement('p');
    welcomeMessage.textContent = `Welcome, ${name}!`;
    header.appendChild(welcomeMessage);
  }
}

// Call the rendering functions
displayWelcomeMessage('Your Name');
renderAboutSection();
renderProjectsSection(projects);
renderContactSection();

In this updated app.ts:

  • We import the functions from the component files using ES6 modules.
  • We define an array of projects with sample data. Replace this with your actual project data.
  • We call the rendering functions (renderAboutSection, renderProjectsSection, and renderContactSection) to render the sections in the HTML.

Making it Interactive

To make your portfolio more interactive, you can add features like:

  • Navigation: Add a navigation bar to allow users to easily navigate between sections.
  • Animations: Use CSS animations or JavaScript libraries like GSAP to add animations to your portfolio.
  • Forms: Implement a contact form to allow visitors to send you messages.
  • Responsiveness: Make your portfolio responsive so it looks good on all devices.

Example: Adding a Navigation Bar

Let’s add a simple navigation bar to your HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My Portfolio</title>
    <link rel="stylesheet" href="src/style.css">
</head>
<body>
    <header>
        <nav>
            <ul>
                <li><a href="#about">About</a></li>
                <li><a href="#projects">Projects</a></li>
                <li><a href="#contact">Contact</a></li>
            </ul>
        </nav>
        <h1>Your Name</h1>
        <p>Software Engineer</p>
    </header>
    <main>
        <section id="about">
            <h2>About Me</h2>
            <p>Write a brief introduction about yourself.</p>
        </section>
        <section id="projects">
            <h2>Projects</h2>
            <!-- Projects will be displayed here -->
        </section>
        <section id="contact">
            <h2>Contact</h2>
            <p>Contact information will go here.</p>
        </section>
    </main>
    <script src="app.js"></script>
</body>
</html>

Add the following CSS to your style.css file:

header nav {
    background-color: #444;
    padding: 0.5rem 0;
}

header nav ul {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    justify-content: center;
}

header nav ul li {
    margin: 0 1rem;
}

header nav ul li a {
    color: #fff;
    text-decoration: none;
    padding: 0.5rem 1rem;
    border-radius: 4px;
}

header nav ul li a:hover {
    background-color: #555;
}

Deployment

Once you’ve built your portfolio, you’ll want to deploy it so others can see it. Here are a few options:

  • GitHub Pages: GitHub Pages is a free service that allows you to host static websites directly from your GitHub repository. It’s a simple and convenient option for portfolios.
  • Netlify/Vercel: Netlify and Vercel are popular platforms for deploying web applications. They offer features like automatic builds, continuous deployment, and content delivery networks (CDNs).
  • Traditional Web Hosting: You can also deploy your portfolio to a traditional web hosting provider. This gives you more control over your server configuration.

Deployment using GitHub Pages:

  1. Create a GitHub Repository: Create a public GitHub repository for your project.
  2. Push Your Code: Push your project code to the repository.
  3. Enable GitHub Pages: Go to the “Settings” tab of your repository, scroll down to the “GitHub Pages” section, and select the branch you want to use for deployment (usually main or gh-pages).
  4. Access Your Portfolio: After a few minutes, your portfolio will be live at a GitHub Pages URL (e.g., your-username.github.io/your-repository-name).

SEO Best Practices

To ensure your portfolio ranks well in search results, follow these SEO best practices:

  • Use Relevant Keywords: Include keywords related to your skills and experience in your content, title, and meta description.
  • Optimize Title and Meta Description: Write a compelling title and meta description that accurately describe your portfolio and encourage clicks.
  • Use Descriptive Alt Text for Images: Provide descriptive alt text for all images to improve accessibility and SEO.
  • Ensure Mobile-Friendliness: Make sure your portfolio is responsive and looks good on all devices.
  • Get Backlinks: Promote your portfolio on social media and other platforms to get backlinks, which can improve your search ranking.
  • Use Semantic HTML: Use semantic HTML elements (<header>, <nav>, <main>, <section>, <article>, <aside>, <footer>) to structure your content.

Summary / Key Takeaways

In this tutorial, we’ve covered the fundamental steps to build a simple web-based portfolio using TypeScript. We’ve explored the benefits of TypeScript, set up a project environment, structured the HTML, written TypeScript code to handle the logic, added CSS for styling, and created reusable components for different sections of the portfolio. We also touched upon making the portfolio interactive, deploying it, and optimizing it for search engines.

By following these steps, you can create a professional-looking portfolio to showcase your skills and projects. Remember to personalize the content, add your own projects, and customize the design to make it your own. With each project, your skills improve, and you become more confident in your ability to build web applications.

FAQ

Q: Can I use a different framework or library instead of plain JavaScript?

A: Yes, you can use frameworks like React, Angular, or Vue.js with TypeScript. However, this tutorial focuses on the fundamentals of TypeScript without any frameworks to make it easier for beginners.

Q: How do I handle images in my portfolio?

A: You can store your images in a folder in your project and use the image URLs in your HTML or TypeScript code. You can also use online image hosting services.

Q: How do I add a contact form?

A: You can use a service like Formspree or Netlify Forms to handle form submissions. Alternatively, you can implement a backend server using Node.js or another backend technology to handle form submissions.

Q: How do I make my portfolio responsive?

A: Use CSS media queries to adjust the layout and styling of your portfolio for different screen sizes. You can also use a CSS framework like Bootstrap or Tailwind CSS to make the process easier.

Q: How do I update my portfolio after deployment?

A: After making changes to your code, you need to recompile your TypeScript code and deploy the updated files to your hosting platform. With platforms like Netlify or Vercel, this process is often automated.

Building a web-based portfolio is an ongoing process. As you learn new skills and complete new projects, you can update your portfolio to reflect your growth and accomplishments. Regularly reviewing and refining your portfolio will ensure it remains a valuable asset in your career journey. It’s a living document that evolves with you, reflecting your expertise and dedication to the craft of software development.