Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

Resume, Portfolio & GitHub Profile  Module 8 – Portfolio website

Planning a developer portfolio website

Plan a portfolio site that proves your work: the five pages it needs, a home page that works in one screen, a GitHub Pages address and safe contact routes.

  • Intermediate
  • 20 minutes
  • Examples run with Python 3.14.8, Node.js 24.21.0 and Pyodide 314.0.7
  • By MySmartCoPilot
Free lesson, Pro answers: 20 minutes
Free: the whole lesson. With a pass: the model answers to its 2 interview questions.

What you will learn

  • Plan the pages a portfolio needs and what each page must prove
  • Write a home page that says who you are and what you build in one screen
  • Publish on GitHub Pages as a user site or a project site, and choose its address
  • Choose contact routes that limit spam and personal exposure

Before you start

What you’ll learn · Before you start

What you will learn

  • Plan the pages a portfolio needs and what each page must prove
  • Write a home page that says who you are and what you build in one screen
  • Publish on GitHub Pages as a user site or a project site, and choose its address
  • Choose contact routes that limit spam and personal exposure

Before you start

On this page

A portfolio site is the one place where you choose the order in which a reader meets your work. A reader who follows the link on your resume may read only its first page, so that page must say who you are, show two or three projects with their results and give a way to reach you, and the rest of the site supports it.

This lesson plans the site of Farah, the invented data analyst of the GitHub lessons: the pages it needs and what each must prove, a home page that works in one screen, an address on GitHub Pages, and contact routes that never hand out her phone number.

Five pages, each with one job

Plan the site from what a reader must be able to check, not from a template. Five pages cover it (MySmartCoPilot guidance), and on a one-page site, which is fine for a student, they become five sections:

Page Its one job What must be on it
Home Say who you are and send the reader to proof Who you are and the work you want, two or three featured case studies with a result each, a link to contact
Projects Prove one project each A case study per project, linked to its code and its demo
About Say who is behind the work A short bio and your current focus
Resume Hand over the document a recruiter files The resume as a web page, and the same resume as a PDF
Contact Let a reader reach you safely An address or a form for job mail, and your city

Step through the path most readers take through Farah’s site:

Interactive · stage by stage A reader's path through Farah's portfolio Step through the pages in the order most readers meet them. Each step says the one job of the page.
A reader's path through Farah's portfolio, step 6 of 6. Showing Home, A case study, About, Resume, Contact. In focus: Contact.two more case studiesHomewho, the work, the proofA case studyone project provedAboutshort bio, current focusResumean HTML page and a PDFContactan address for job mail

The drawing shows the whole scene; its 6 steps are listed below.

Every step as text
  1. The home page. A recruiter follows the link on Farah's resume and lands on her home page. In its first lines it says who she is and the work she wants, then shows three featured case studies, each with one result.
  2. One case study. The reader opens the library loans dashboard. The page proves one project: the problem, her part, the approach and the result, with links to the code and the demo.
  3. And the others. From there the reader can go back for the rainfall analysis and her ward maps fix. Two or three studies are enough; each one is a page the reader can finish.
  4. About. The about page says who is behind the work in a few lines: what she studies, what she wants to do next, and nothing a stranger should not know.
  5. The resume. The resume page shows the resume as a web page that reads on a phone, and offers the same resume as a PDF to download and file.
  6. Contact. The contact page gives an address she uses only for job mail and a link to LinkedIn. It names her city, never her street or her phone number.

Each case-study page is the kind of page writing a project case study builds. The program checks Farah’s first plan and her final one against the table:

Two plans of Farah's portfolio against the five jobs Python · sitemap/sitemap_check.py
# Checks the plan of an invented data analyst's portfolio site, Farah's, before and after, against the pages this
# lesson plans (MySmartCoPilot guidance): a home page that features two or three case studies and links the contact
# route, a page for each case study, an about page, a resume page with an HTML version and a PDF, and a contact route
# without a home address or a personal phone number. Press Edit, describe your own site in MINE, and run it again.
import re

BEFORE = {
    "/": {"kind": "home", "links": ["/about/", "/blog/"]},
    "/about/": {"kind": "about", "links": ["/"]},
    "/blog/": {"kind": "blog", "links": ["/"]},
    "/projects/": {"kind": "list", "links": ["/projects/library-loans/"]},
    "/projects/library-loans/": {"kind": "case-study", "links": ["/"]},
    "/contact/": {"kind": "contact", "text": "Call me on +91 90000 12345, or visit Flat 4B, 12 Lake Road, Kolkata."},
}
AFTER = {
    "/": {"kind": "home", "links": ["/projects/library-loans/", "/projects/rainfall/", "/projects/ward-maps/",
                                    "/resume/", "/contact/"]},
    "/projects/library-loans/": {"kind": "case-study", "links": ["/", "/resume/"]},
    "/projects/rainfall/": {"kind": "case-study", "links": ["/"]},
    "/projects/ward-maps/": {"kind": "case-study", "links": ["/"]},
    "/about/": {"kind": "about", "links": ["/"]},
    "/resume/": {"kind": "resume", "formats": ["html", "pdf"], "links": ["/"]},
    "/contact/": {"kind": "contact",
                  "text": "Write to farah.jobs@example.com, or find me on LinkedIn. I live in Kolkata."},
}
MINE = None  # your own site, in the same shape
PHONE = re.compile(r"\+?\d[\d -]{8,}\d")
STREET = re.compile(r"\b(?:flat|road|street|lane|nagar|house)\b", re.I)


def checks(site):
    pages = list(site.values())
    home = next((p for p in pages if p["kind"] == "home"), {"links": []})
    studies = [url for url, p in site.items() if p["kind"] == "case-study"]
    featured = [url for url in home["links"] if url in studies]
    resume = next((p for p in pages if p["kind"] == "resume"), {})
    contact = next((p for p in pages if p["kind"] == "contact"), {})
    linked = [site[url]["kind"] for url in home["links"] if url in site]
    return {
        "two or three case studies on the home page": 2 <= len(featured) <= 3,
        "a page for each case study": len(studies) >= 2,
        "an about page": any(p["kind"] == "about" for p in pages),
        "a resume in HTML and as a PDF": {"html", "pdf"} <= set(resume.get("formats", [])),
        "a contact route linked from home": bool(contact) and "contact" in linked,
        "no phone number or street address": bool(contact) and not PHONE.search(contact["text"])
        and not STREET.search(contact["text"]),
    }


for label, site in [("before", BEFORE), ("after", AFTER)] + ([("mine", MINE)] if MINE else []):
    found = checks(site)
    print(f"{label}: {len(site)} pages, {sum(found.values())} of {len(found)} checks pass")
    for name, ok in found.items():
        if not ok:
            print(f"  fails: {name}")

Output

before: 6 pages, 1 of 6 checks pass
  fails: two or three case studies on the home page
  fails: a page for each case study
  fails: a resume in HTML and as a PDF
  fails: a contact route linked from home
  fails: no phone number or street address
after: 7 pages, 6 of 6 checks pass

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 sitemap_check.py

Her first plan passed 1 check of 6. Its home page linked an about page and a blog, but no case study and no contact page; it had one case study and no resume, and its contact page gave her phone number and street address. The final plan has seven pages and passes all six. A blog can stay, but it is not one of the five jobs, so it no longer takes the space on the home page that the case studies need.

Checkpoint

Check: Five pages and their jobs

  1. Question 1 of 2 Which of these belong on a portfolio's home page? Choose every one.

    Choose every answer that is right.

    Show the answer: Question 1 of 2

    Answer:

    • A link to the contact page
    • Two or three featured case studies, each with a result
    • Who you are and the work you want

    The home page says who you are and the work you want, features two or three case studies with a result each, and links to contact. The other pages each prove one thing: a project, who you are, your resume, how to reach you.

  2. Question 2 of 2 Why did Farah's first plan fail the check for two or three case studies on the home page?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: Its home page linked an about page and a blog, but no case study

    The first plan's home page linked /about/ and /blog/. The final plan links three case studies, the resume and the contact page from the home page, and passes all six checks.

The home page answers three questions in one screen

The top of the home page, its hero: The first block of a web page, shown before the reader scrolls. On a portfolio's home page it says who you are, the work you want and what you build., answers who you are, what you build and where the proof is, before the reader scrolls. Farah’s first hero spends its words on enthusiasm; the second spends about as many on facts. The program checks both:

Two hero texts for Farah's home page, checked Python · hero/hero_check.py
# Checks two hero texts, the first words of Farah's home page, for what a reader needs on the first screen: her name,
# the role she wants, what she builds, and one result with a number, in at most 40 words. The checks and the 40-word
# budget are MySmartCoPilot guidance. Press Edit, paste your own hero text into MINE, and run it again.
import re

BEFORE = ("Welcome to my corner of the internet! I'm a passionate, curious and detail-oriented data enthusiast who "
          "loves turning chaos into clarity. Explore my journey, my skills and my projects below, and let's connect!")
AFTER = ("Farah Siddiqui, data analyst, looking for a first full-time role. I build dashboards and reports from public "
         "and college data: the college library now reorders books from my dashboard of three years of loans.")
MINE = None  # your own hero text
NAME = "Farah"
ROLE = re.compile(r"\b(analyst|developer|engineer|designer|scientist)\b", re.I)
BUILDS = re.compile(r"\b(dashboards?|reports?|pipelines?|models?|apps?|APIs?|services?|websites?|tools?)\b", re.I)


def checks(text):
    words = re.findall(r"[\w'-]+", text)
    return {
        "her name": NAME in text,
        "the role she wants": bool(ROLE.search(text)),
        "what she builds": bool(BUILDS.search(text)),
        "a result with a number": bool(re.search(r"\b\d|\b(?:one|two|three|four|five|six|seven|eight|nine|ten)\b", text)),
        "at most 40 words": len(words) <= 40,
    }, len(words)


for label, text in [("before", BEFORE), ("after", AFTER)] + ([("mine", MINE)] if MINE else []):
    found, count = checks(text)
    print(f"{label}: {count} words, {sum(found.values())} of {len(found)} checks pass")
    for name, ok in found.items():
        if not ok:
            print(f"  fails: {name}")

Output

before: 33 words, 1 of 5 checks pass
  fails: her name
  fails: the role she wants
  fails: what she builds
  fails: a result with a number
after: 34 words, 5 of 5 checks pass

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 hero_check.py

The first hero, 33 words, passes 1 check of 5: it is short, and it says nothing else a reader can use. The second, 34 words, passes all five. It names a role and a kind of work, so a reader knows at once which postings she fits, and it gives one result that the case study linked under it can prove. The budget of 40 words is MySmartCoPilot guidance: it leaves room on a phone’s first screen for the case studies, which are the next thing a reader looks for. Under the hero, show each featured case study as a short card: its title, one line with its result and a link.

A greeting where the facts should be

Wrong: “Welcome to my corner of the internet! I’m a passionate data enthusiast.” Right: “Farah Siddiqui, data analyst, looking for a first full-time role. I build dashboards and reports from public and college data.” The greeting spends the reader’s first seconds on words that could open anyone’s site.

Checkpoint

Check: A home page that works in one screen

  1. Question 1 of 2 Which hero text passes all five of the lesson's checks?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: Farah Siddiqui, data analyst, looking for a first full-time role. My dashboard of three years of library loans now decides which books the college reorders.

    A hero answers who you are, the work you want, what you build and one result, in about 40 words, so that the case studies under it still fit on a phone's first screen.

  2. Question 2 of 2 At most how many words does this lesson's guidance give the hero text of a home page?

    Type a number.

    Show the answer: Question 2 of 2

    Answer: 40 words

    About 40 words, MySmartCoPilot guidance, leaves room on a phone's first screen for the case-study cards. Farah's second hero uses 34.

GitHub Pages gives a site one of two kinds of address

GitHub Pages serves a site from a repository, in two kinds. A user site: A GitHub Pages site published from a repository named <owner>.github.io, in lower case, and served at https://<owner>.github.io/. Each account can have one. is published from a repository named <owner>.github.io, in lower case, and served at https://<owner>.github.io/; an account has one. Any other repository can publish a project site: A GitHub Pages site published from any other repository of an account and served at https://<owner>.github.io/<repository>/, or under the user site's custom domain. at https://<owner>.github.io/<repository>/. In the repository’s Pages settings you choose its publishing source: What GitHub Pages publishes a site from, chosen in the repository's Pages settings: a branch, from its root or its /docs folder, or a GitHub Actions workflow.: a branch, from its root or its /docs folder, or a GitHub Actions workflow. The program works out the address of each kind for Farah’s account:

The addresses GitHub Pages gives Farah's sites Python · address/pages_address.py
# Works out the address GitHub Pages gives each of an account's sites, by the rules of GitHub Docs: a user site is
# published from a repository named <owner>.github.io, in lower case, and served at https://<owner>.github.io/, one per
# account; any other repository publishes a project site at https://<owner>.github.io/<repository>/; a custom domain on
# the user site is used by the account's project sites too, unless a project site sets its own. The account and its
# domains are invented (.example is a name reserved for examples). Press Edit, try your own names, and run it again.
OWNER = "Farah-Example"


def address(repository, user_domain=None, own_domain=None):
    owner = OWNER.lower()
    if repository.lower() == f"{owner}.github.io":
        if repository != f"{owner}.github.io":
            return f"no site: name the repository {owner}.github.io, in lower case"
        return f"https://{user_domain}/" if user_domain else f"https://{owner}.github.io/"
    if own_domain:
        return f"https://{own_domain}/"
    return f"https://{user_domain}/{repository}/" if user_domain else f"https://{owner}.github.io/{repository}/"


CASES = [
    ("The user site", "farah-example.github.io", None, None),
    ("A project site", "library-loans-dashboard", None, None),
    ("The user site, with a custom domain", "farah-example.github.io", "www.farah.example", None),
    ("The project site, under that domain", "library-loans-dashboard", "www.farah.example", None),
    ("A project site with its own domain", "rainfall-analysis", "www.farah.example", "rain.farah.example"),
    ("A user site named with capitals", "Farah-Example.github.io", None, None),
]
for label, repository, user_domain, own_domain in CASES:
    print(f"{label}:\n  {repository} -> {address(repository, user_domain, own_domain)}")

Output

The user site:
  farah-example.github.io -> https://farah-example.github.io/
A project site:
  library-loans-dashboard -> https://farah-example.github.io/library-loans-dashboard/
The user site, with a custom domain:
  farah-example.github.io -> https://www.farah.example/
The project site, under that domain:
  library-loans-dashboard -> https://www.farah.example/library-loans-dashboard/
A project site with its own domain:
  rainfall-analysis -> https://rain.farah.example/
A user site named with capitals:
  Farah-Example.github.io -> no site: name the repository farah-example.github.io, in lower case

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 pages_address.py

The portfolio belongs on the user site, at the shortest address the account has, and each demo on a project site. A custom domain set on the user site moves the project sites under it too, unless one sets its own, as the rainfall analysis does. Take your own domain only if you will keep renewing it. GitHub recommends a www subdomain and verifying the domain before you add it, because a disabled site whose custom domain still points at GitHub is at risk of a domain takeover: Someone else serving their own content at your domain. GitHub warns that a disabled Pages site with a custom domain is at risk, and verifying the domain stops other users taking it.. Answer two questions to choose:

Interactive · answer and compare Which address fits the site? Answer two questions. The table rules out what does not fit and says why.
Is this your main portfolio, or the demo of one project?
Do you own a domain name, and will you keep renewing it after the job search?

Answer the questions above: the table then marks what fits your case and says why the rest does not.

Three kinds of GitHub Pages address against what a reader sees and what you must look after
Address What a reader sees How many per account What you set up What to watch
User site Looks like: https://farah-example.github.io/ Good short, and it carries your username Mixed one, from the repository <owner>.github.io Good that repository and a publishing source Good the repository name stays in lower case
Project site Looks like: https://farah-example.github.io/rainfall-analysis/ Mixed longer: the repository name follows the account Good one for each repository Good a publishing source in any repository Mixed it moves under the user site's custom domain, if there is one
User site on your own domain Looks like: https://www.farah.example/ Good the same address on every profile and resume Mixed one domain, which project sites share unless they set their own Poor DNS records, a verified domain, a www subdomain, Enforce HTTPS Poor a disabled site whose domain still points at GitHub risks a takeover
How the answers decide
  • “Is this your main portfolio, or the demo of one project?” My main portfolio: rules out Project site. A portfolio goes on the user site, at the shortest address the account has; project sites are for the demos it links.
  • “Is this your main portfolio, or the demo of one project?” The demo of one project: rules out User site and User site on your own domain. An account has one user site, and the portfolio needs it. A demo gets a project site in its own repository.
  • “Do you own a domain name, and will you keep renewing it after the job search?” No, or not after the search: rules out User site on your own domain. A custom domain needs looking after: a lapsed one can be bought by anyone, and one still pointing at GitHub after the site goes is at risk of a takeover. The github.io address needs neither.
  • “Do you own a domain name, and will you keep renewing it after the job search?” Yes, for years: adds a caveat to User site on your own domain. Verify the domain on GitHub before you add it, use a www subdomain as GitHub recommends, and turn on Enforce HTTPS.

In short: the portfolio on the user site, each demo on a project site, and a domain of your own only if you will look after it.

GitHub Pages’ limits are far above what a portfolio needs. A published site may be at most 1 GB; traffic has a soft ceiling of 100 GB of bandwidth monthly, and builds a soft ceiling of 10 per hour, which is lifted when your own Actions workflow builds the site. It is not meant for running an online business or for sensitive transactions such as passwords or card numbers, a site is public on the internet even when its repository is private, and a push can take up to 10 minutes to appear. A new site on github.io is served over HTTPS; with a custom domain, select Enforce HTTPS in the Pages settings. For other hosts and their rules, see hosting demos without paying.

Build with what you know

Plain HTML and CSS are enough for five pages, and they publish from a branch with no build tool of your own. A framework is a choice you should be able to justify in an interview, not a requirement; publishing a static site covers the files.

Checkpoint

Check: GitHub Pages addresses

  1. Question 1 of 2 Farah's username is shown as Farah-Example. What must the repository of her user site be called?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: farah-example.github.io

    A user site is published from a repository named <owner>.github.io in lower case and is served at https://farah-example.github.io/. Each account has one.

  2. Question 2 of 2 Farah sets www.farah.example as her user site's custom domain. Where is the project site of library-loans-dashboard served?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: https://www.farah.example/library-loans-dashboard/

    A custom domain on the user site is used by every project site of the same account, unless a project site sets its own, which overrides it.

Contact routes that do not expose you

GitHub says it records and keeps the IP address of every visitor to a GitHub Pages site, for security, whether or not that visitor is signed in to GitHub. Say so in a line on the site, and say so as well about anything you add, such as an analytics script. The same care runs the other way: whatever you publish about yourself stays findable long after the job search.

Route What it exposes What to watch
An address only for job mail An address you can retire after the search Check it as often as your main inbox
A form from a form service Nothing until you reply Read its terms: it stores what visitors send
A link to LinkedIn What your profile already shows Keep the profile consistent with the site
Your personal phone number Calls and messages from anyone, for years Keep it for the resumes you send, never the site
Your home address Where you live Never: your city is enough

The resume you offer as a PDF on the site is public too, so give it the same contact block as the site: the job-mail address and your city. Once the site is live, search your name. Google’s Results about you looks for search results carrying your phone number, home address or e-mail address, and you can ask Google to drop each one from its results; what not to publish covers the rest of a job seeker’s privacy.

Key idea

A public site is public for good: give it one route for job mail and your city, and keep your phone number and home address for the resumes you send to people you chose.

QR Code Generator Print your portfolio's address as a QR code on the paper resume you take to a campus fair.

Checkpoint

Check: Contact routes that do not expose you

  1. Question 1 of 2 Where does Farah's personal phone number belong?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: Only on the resumes she sends to people she chose, never on the site or its public PDF

    Give the site and its public PDF one route for job mail and your city. Keep the phone number for the resumes you send to people you chose.

  2. Question 2 of 2 What does GitHub log when someone visits a GitHub Pages site?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: The visitor's IP address, stored for security, whether or not they are signed in to GitHub

    GitHub records and keeps every visitor's IP address for security, signed in or not. Say so on the site, and say so about any analytics you add.

Practise: plan Arjun’s site

Arjun’s first plan has a blog but no about page, a resume without a web version, and his phone number and street on the contact page. Fix it from his records; the sample tests check the five jobs of this lesson:

Exercise · Easy · Python

Plan a portfolio site that a reader can check

Arjun, the invented student whose library seat booker this track has followed, plans his portfolio site. SITE in arjun_site.py is his first plan: each page's address, its kind (home, case-study, about, resume, contact or anything else), the pages it links and, for the contact page, its text. His records:

  • Case studies: the seat booker (/projects/seat-booker/), which cut no-shows from 31 % to 12 %, and an API for the hostel's mess menu (/projects/mess-menu-api/).
  • About him: a final-year student in Nagpur who wants a backend role.
  • Job mail: arjun.jobs@example.com.

Fix SITE so that it has the five jobs of this lesson:

  • a home page that links both case studies and the contact page;
  • an about page;
  • a resume page that offers both "html" and "pdf" in its formats;
  • a contact page with a route for job mail and no phone number or street address.

The blog can stay or go.

Starter code · arjun_site.py

# Arjun's first plan for his portfolio site: each page's address, its kind, the pages it links and, for the contact
# page, its text. Fix it from his records in the prompt.
SITE = {
    "/": {"kind": "home", "links": ["/blog/"]},
    "/blog/": {"kind": "blog", "links": ["/"]},
    "/projects/seat-booker/": {"kind": "case-study", "links": ["/"]},
    "/projects/mess-menu-api/": {"kind": "case-study", "links": ["/"]},
    "/resume/": {"kind": "resume", "formats": ["pdf"], "links": ["/"]},
    "/contact/": {"kind": "contact", "links": ["/"], "text": "Phone: +91 90000 00000. Home: 7 Station Road, Nagpur."},
}
The sample tests · test_site.py
import re

from arjun_site import SITE

PHONE = re.compile(r"\+?\d[\d -]{8,}\d")
STREET = re.compile(r"\b(?:flat|road|street|lane|nagar|house)\b", re.I)


def pages(kind):
    return [url for url, page in SITE.items() if page["kind"] == kind]


def test_home_features_case_studies():
    """has a home page that features two or three case studies, each with a page of its own"""
    assert pages("home"), "the site needs a home page"
    studies = pages("case-study")
    featured = [url for url in SITE[pages("home")[0]]["links"] if url in studies]
    assert len(studies) >= 2, "give at least two projects a case-study page"
    assert 2 <= len(featured) <= 3, f"the home page links {len(featured)} case studies: feature two or three"


def test_about_and_resume():
    """has an about page and a resume page with an HTML version and a PDF"""
    assert pages("about"), "add an about page: a short bio and your current focus"
    assert pages("resume"), "add a resume page"
    formats = set(SITE[pages("resume")[0]].get("formats", []))
    assert {"html", "pdf"} <= formats, f"the resume page offers {sorted(formats)}: give an HTML page and a PDF"


def test_contact_linked_and_safe():
    """links a contact page from home, with a route for job mail and no phone number or street address"""
    assert pages("contact"), "add a contact page"
    contact = SITE[pages("contact")[0]]
    assert pages("contact")[0] in SITE[pages("home")[0]]["links"], "link the contact page from the home page"
    text = contact["text"]
    assert "@" in text or "form" in text.lower(), "give an e-mail address for job mail, or a form"
    assert not PHONE.search(text), "no phone number on a public page"
    assert not STREET.search(text), "no street address on a public page: a city is enough"
A hint

Add an "/about/" page with "kind": "about", then put both case-study addresses and "/contact/" in the home page's links. On the contact page, replace the phone number and the street with his job-mail address.

The sample tests run on this device, in your browser (Pyodide): nothing is sent to mysmartcopilot.com. The first run downloads Python (about 13.5 MB), which is kept for the next runs. A check in your browser is feedback for you, not proof that the code is right for every input.

Then test yourself on the plan, the hero, the address and the contact routes; the questions begin where your answers have been weakest:

Practice that adapts to you

Practise this lesson

11 questions about 4 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.

  1. Question 1 of 11 Is a one-page portfolio site acceptable for a student?

    Choose one answer.

    Show the answer: Question 1 of 11

    Answer: Yes, with the five jobs as five sections of the page

    A one-page site is fine for a student: the home, projects, about, resume and contact jobs become five sections of the same page.

  2. Question 2 of 11 Why does the resume page offer both a web page and a PDF?

    Choose one answer.

    Show the answer: Question 2 of 11

    Answer: The web page reads well on a phone, and the PDF is the file a recruiter downloads and keeps

    The web page is for reading in the browser, especially on a phone; the PDF, with the same content, is for filing. Both carry the same public contact block.

  3. Question 3 of 11 Farah wants to keep her blog. Where does it go?

    Choose one answer.

    Show the answer: Question 3 of 11

    Answer: In the menu or on the about page, but not in the home page's space for case studies

    Keep extras such as a blog where readers who want them can find them, without taking the space the home page gives to who you are and to two or three case studies.

  4. Question 4 of 11 Which part of Farah's second hero tells a reader at once which postings she fits?

    Choose one answer.

    Show the answer: Question 4 of 11

    Answer: Data analyst, looking for a first full-time role

    The hero names her, the role she wants, what she builds and one result. The role is what lets a reader decide in a second whether she fits their posting.

  5. Question 5 of 11 What should come right under the hero of a portfolio's home page?

    Choose one answer.

    Show the answer: Question 5 of 11

    Answer: Two or three case-study cards, each with a title, a line with its result and a link

    Under the hero, short cards for the featured case studies keep the proof on or near the first screen, each with its result and a link to the full case study.

  6. Question 6 of 11 How many user sites can one GitHub account have?

    Type a number.

    Show the answer: Question 6 of 11

    Answer: 1 user site

    One user site per account, from the repository <owner>.github.io. Every other repository can publish a project site under it.

  7. Question 7 of 11 Which of these is one of GitHub Pages' limits?

    Choose one answer.

    Show the answer: Question 7 of 11

    Answer: A published site of at most 1 GB

    GitHub Pages limits a published site to 1 GB, with a soft bandwidth limit of 100 GB a month and a soft limit of 10 builds an hour that does not apply to your own Actions workflow.

  8. Question 8 of 11 After her job search, Farah disables her site but leaves her custom domain pointing at GitHub. What is the risk?

    Choose one answer.

    Show the answer: Question 8 of 11

    Answer: A domain takeover, which verifying the domain on GitHub prevents

    If a GitHub Pages site is disabled but has a custom domain set up, it is at risk of a domain takeover. Verify the domain before adding it, and update or remove its DNS records when you stop using it.

  9. Question 9 of 11 Which contact route fits a portfolio site best?

    Choose one answer.

    Show the answer: Question 9 of 11

    Answer: An e-mail address you use only for job mail

    A job-mail address, a form you have read the terms of, or a LinkedIn link, with your city. Never your phone number or home address on a public page.

  10. Question 10 of 11 The resume PDF that Farah offers on her site still shows her phone number. What does she do?

    Choose one answer.

    Show the answer: Question 10 of 11

    Answer: Give the public PDF the site's contact block, her job-mail address and her city

    The public PDF carries the same contact block as the site. The resumes she sends to people she chose can carry her phone number.

  11. Question 11 of 11 Farah adds an analytics script to her site. What does she tell visitors?

    Choose one answer.

    Show the answer: Question 11 of 11

    Answer: That GitHub Pages logs visitors' IP addresses for security, and what her analytics script measures

    GitHub logs and stores visitors' IP addresses for security. Say so on the site, together with what any script you add measures.

Interview questions

Warm-up (fresher to mid-level): What pages does a developer portfolio site need?

Five jobs, as five pages or as five sections of one page. A home page says who I am and the work I want, and features two or three case studies with a result each. Each case study proves one project, with links to its code and its demo. An about page gives a short bio and my current focus, a resume page offers the resume as a web page and as a PDF, and a contact page gives an address for job mail and my city, never my phone number or street.

Warm-up (fresher to mid-level): How does a GitHub Pages user site differ from a project site?

A user site is published from a repository named after my account, <owner>.github.io in lower case, and is served at https://<owner>.github.io/; an account has only one. A project site can be published from any other repository and is served at https://<owner>.github.io/<repository>/. I put my portfolio on the user site and each project’s demo on its own project site. If I set a custom domain on the user site, the project sites move under that domain too.

Two questions of this module’s bank go further:

Model answers open with any pass: ₹79 for 1 week ($2.99), one payment that never renews.

  1. Fresher to mid

    Applications open in two weeks. You have three projects with written case studies, but no site. Do you build one page or five, on which host and at which address, and what do you leave out until later?

    Model answer, Pro. Model answers open with any pass; prices are in the notice on this page. First step and follow-ups

  2. Fresher to mid

    Two weeks after your portfolio goes live, spam fills your inbox and a stranger calls the phone number in the resume PDF linked from the site. What do you change on the site, and how do you limit what is already out?

    Model answer, Pro. First step and follow-ups

Flashcards · 8 cards

Recall it, then check

Say the answer to yourself before you look: recalling it is what makes it stick.

  1. Which five jobs must a developer portfolio site do?

    A home page that says who you are and sends the reader to proof, a case study per project, an about page, the resume as a web page and a PDF, and a safe way to make contact. A student's one-page site can do them as five sections.

  2. What must the home page of a portfolio hold?

    Who you are and the work you want, two or three featured case studies with a result each, and a link to contact you. A blog may stay on the site, but it should not take the case studies' place.

  3. What should a portfolio's hero say, and in about how many words?

    Who you are, the work you want, what you build and one result, in about 40 words, so the featured case studies still fit on a phone's first screen. A greeting spends the reader's first seconds on nothing.

  4. How does a GitHub Pages user site differ from a project site?

    A user site is published from the account's one repository called <owner>.github.io, all in lower case, and is served at that address. Any other repository can publish a project site at <owner>.github.io/<repository>/.

  5. When should a portfolio on GitHub Pages get a custom domain, and how do you protect it?

    Only if you will keep renewing it. GitHub recommends a www subdomain and verifying the domain before adding it, since a disabled site whose domain still points at GitHub is open to a domain takeover.

  6. What are GitHub Pages' main limits for a portfolio?

    Published sites of up to 1 GB, soft limits of 100 GB of monthly bandwidth and 10 builds an hour unless your own Actions workflow builds the site. GitHub does not intend it for an online business or for sensitive data such as passwords and card numbers.

  7. Which contact details belong on a public portfolio site?

    An address used only for job mail, or a form service, plus your city and perhaps a LinkedIn link. Keep your personal phone number and home address for the resumes you send, and give the site's PDF resume the same contact block.

  8. What does GitHub record about visitors to a GitHub Pages site?

    The IP address of each visitor, kept for security reasons, signed-in GitHub user or not. Say so on the site, along with anything you add yourself, such as an analytics script.

Key takeaways

  • A portfolio has five jobs: a home page that sends the reader to proof, a case study per project, an about page, a resume as a web page and a PDF, and a contact route.
  • The home page’s first words say who you are, the work you want, what you build and one result, in about 40 words, with two or three case studies right under them.
  • GitHub Pages serves one user site per account at <owner>.github.io and a project site per repository under it; take a custom domain only if you will keep renewing it, and verify it.
  • Give the site one route for job mail and your city, never your phone number or home address, and say that GitHub Pages logs visitors’ IP addresses.

Terms in this lesson

domain takeover
Someone else serving their own content at your domain. GitHub warns that a disabled Pages site with a custom domain is at risk, and verifying the domain stops other users taking it.
hero
The first block of a web page, shown before the reader scrolls. On a portfolio's home page it says who you are, the work you want and what you build.
project site
A GitHub Pages site published from any other repository of an account and served at https://<owner>.github.io/<repository>/, or under the user site's custom domain.
publishing source
What GitHub Pages publishes a site from, chosen in the repository's Pages settings: a branch, from its root or its /docs folder, or a GitHub Actions workflow.
user site
A GitHub Pages site published from a repository named <owner>.github.io, in lower case, and served at https://<owner>.github.io/. Each account can have one.

References

Related tools

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.