Collection
Query, filter, sort, and paginate any Markdown content — blog posts, publications, projects — into a styled grid or list.
Filterable project cards with tag filtering and smooth animations — a portfolio grid for developers and studios.
Add it to any Hugo page's sections list — no build step.
Quick start
Drop this into your page's front matter, under the sections list. Edit the values, and HugoBlox renders the block — no build step.
- block: portfolio
id: projects
content:
title: Featured Projects
subtitle: A selection of my recent work
count: 6
filters:
folders:
- projects
buttons:
- name: All
tag: "*"
- name: Full-Stack
tag: Full-Stack
- name: Frontend
tag: Frontend
- name: Backend
tag: Backend
default_button_index: 0
archive:
enable: true
text: View All Projects
design:
columns: 3Overview
A flexible, filterable portfolio block for showcasing work with Alpine.js-powered filtering and modern glass morphism styling.
Versatile Use Cases: Software projects, research papers, design work, photography, teaching portfolios, case studies, publications, and more.
- block: portfolio
id: portfolio
content:
title: "My Work"
subtitle: "A selection of recent projects"
count: 6
filters:
folders:
- projects # Or: research, portfolio, work, teaching, etc.
buttons:
- name: All
tag: '*'
- name: Category A
tag: CategoryA
- name: Category B
tag: CategoryB
default_button_index: 0
archive:
# Auto-shown if more items exist than displayed
# Optionally customize:
# enable: false # Explicitly hide
# link: "/work/" # Custom URL
# text: "Browse All" # Custom text
design:
columns: 3
fallback_icon: code-bracket # Or: academic-cap, paint-brush, camera, etc.
Each portfolio item should include the following frontmatter:
---
title: "Item Title"
date: 2024-01-15
summary: "Brief description of the work"
tags:
- Category
- Subcategory
- Tag
tech_stack: # Or think of as: tools, methods, skills, materials
- Tool 1
- Tool 2
- Tool 3
links:
- type: custom # Or: github, live, pdf, video, etc.
url: https://example.com
label: View Project
icon: globe-alt # Optional
status: "Completed" # Or: Live, Published, In Progress, etc.
featured: true
---
| Parameter | Type | Default | Description |
|---|---|---|---|
title | string | - | Section title |
subtitle | string | - | Section subtitle |
count | integer | 0 (all) | Number of projects to display (set to 0 or omit to show all) |
filters.folders | array | ["projects"] | Content folders to query |
buttons | array | [{name: "All", tag: "*"}] | Filter buttons |
default_button_index | integer | 0 | Default active filter |
archive.enable | boolean | auto | Show "View All" link (auto-shown if more projects exist, set to false to hide) |
archive.link | string | auto | Archive URL (defaults to first folder in filters.folders) |
archive.text | string | i18n | Archive link text (uses i18n portfolio_view_all) |
status.text | string | - | Override status badge text (falls back to each item's status) |
| Parameter | Type | Default | Description |
|---|---|---|---|
columns | integer | 3 | Grid columns (2, 3, or 4) |
fallback_icon | string | code-bracket | Icon shown when item has no image. Supports all Hugo Blox icon packs (hero, brands, devicon, emoji, custom). Format: icon-name or pack/icon-name |
status_badge.enable | boolean | true | Show or hide the status badge |
Each link supports the following properties:
type: Link type (github, live, demo, or custom)url: Link URLlabel: Custom label text (optional, overrides default)icon: Custom icon (optional, overrides default - supports all icon packs)| Type | Icon | Default Label |
|---|---|---|
github | brands/github | "Code" |
live | globe-alt | "Live" |
demo | play | "Demo" |
| Other | link | "Link" |
Note: Labels are shared with the project page header, so setting them in frontmatter ensures consistency across card and page views.
Icon Examples:
links:
- type: custom
url: "..."
label: "Watch Video"
icon: play-circle # Hero icon (default pack)
- type: custom
url: "..."
label: "View on GitHub"
icon: brands/github # Brand icon
- type: pdf
url: "paper.pdf"
label: "Read Paper"
icon: document-text # Hero icon
- type: custom
url: "..."
label: "Python Code"
icon: devicon/python # Devicon
| Status | Color |
|---|---|
Live | Emerald/Green |
WIP | Amber/Yellow |
Archived | Gray |
Note: You can use any custom status text. Color coding: emerald for active/live/published, amber for in-progress, gray for archived/completed.
- block: portfolio
content:
title: "Featured Projects"
filters:
folders: [projects]
buttons:
- {name: All, tag: '*'}
- {name: Full-Stack, tag: Full-Stack}
- {name: Frontend, tag: Frontend}
design:
fallback_icon: code-bracket
Project frontmatter:
title: "E-Commerce Platform"
tags: [Full-Stack, React, Node.js]
tech_stack: [React, TypeScript, PostgreSQL]
links:
- {type: github, url: "...", label: Code}
- {type: live, url: "...", label: Demo}
status: "Live"
- block: portfolio
content:
title: "Research Projects"
filters:
folders: [research]
buttons:
- {name: All, tag: '*'}
- {name: Machine Learning, tag: ML}
- {name: Computational Biology, tag: CompBio}
design:
fallback_icon: academic-cap # Or: beaker, emoji/microscope, devicon/python
columns: 2
Research project frontmatter:
title: "Neural Network Optimization Study"
tags: [ML, Optimization, Deep Learning]
tech_stack: [Python, PyTorch, CUDA, NumPy] # Or rename to "methods", "tools"
links:
- {type: pdf, url: "paper.pdf", label: Read Paper}
- {type: code, url: "github.com/...", label: Code}
- {type: dataset, url: "...", label: Dataset}
status: "Published"
- block: portfolio
content:
title: "Design Work"
filters:
folders: [portfolio]
buttons:
- {name: All, tag: '*'}
- {name: Brand Design, tag: Branding}
- {name: UI/UX, tag: UI/UX}
- {name: Illustration, tag: Illustration}
design:
fallback_icon: paint-brush # Or: camera, emoji/art, brands/dribbble
columns: 3
Design project frontmatter:
title: "Acme Corp Brand Identity"
tags: [Branding, Logo Design, Print]
tech_stack: [Adobe Illustrator, Photoshop, Figma] # Tools used
links:
- {type: custom, url: "behance.net/...", label: View on Behance, icon: globe-alt}
- {type: pdf, url: "case-study.pdf", label: Case Study}
status: "Completed"
- block: portfolio
content:
title: "Courses & Materials"
filters:
folders: [teaching]
buttons:
- {name: All, tag: '*'}
- {name: Undergraduate, tag: Undergrad}
- {name: Graduate, tag: Grad}
design:
fallback_icon: document-text
Course frontmatter:
title: "Introduction to Data Science"
tags: [Undergrad, Statistics, Programming]
tech_stack: [Python, R, Jupyter, Pandas] # Tools taught
links:
- {type: custom, url: "syllabus.pdf", label: Syllabus, icon: document-text}
- {type: custom, url: "github.com/...", label: Course Materials, icon: brands/github}
status: "Spring 2024"
Rename fields conceptually - While tech_stack is the parameter name, you can use it for:
Custom link types - Beyond github, live, demo:
pdf for papers, reports, case studiesdataset for research datavideo for presentations, demosslides for slide decksFlexible status badges - Use any text:
Icon selection - Choose an appropriate fallback_icon:
code-bracket - Software/developmentacademic-cap - Academic/educationbeaker - Research/sciencepaint-brush - Art/designcamera - Photographydocument-text - Writing/documentationstar - Featured/highlightsbrands/ prefix):
brands/github - GitHub projectsbrands/linkedin - Professional workbrands/dribbble - Design workdevicon/ prefix):
devicon/python - Python projectsdevicon/react - React projectsdevicon/docker - DevOps workemoji/ prefix or direct unicode):
emoji/rocket or 🚀emoji/art or 🎨emoji/microscope or 🔬assets/media/icons/<pack>/ and use <pack>/<name>Flexibility
Switch the block's design with these presets — no custom CSS.
columnsNumber of columns (2, 3, or 4)Reference
Every option the Portfolio block accepts, generated from its schema.
Properties set under the block's content key.
| Property | Type | Default | Description |
|---|---|---|---|
title | string | — | Section title (supports Markdown) |
subtitle | string | — | Section subtitle (supports Markdown) |
count | integer | 6 | Maximum number of projects to display when no filter buttons are used (0 means unlimited) |
sort_by | Date | date | Title | title | Weight | weight | Lastmod | lastmod | Date | Field to sort by |
sort_ascending | boolean | false | Sort in ascending order |
filters | object | — | Content filtering options |
filters.folders | string[] | projects | Content folders to query projects from |
buttons | object[] | [object Object] | Filter buttons configuration |
buttons[].namerequired | string | — | Button display text |
buttons[].tagrequired | string | — | Tag to filter by (* for all) |
default_button_index | integer | 0 | Index of the default active filter button |
archive | object | — | Archive link configuration |
archive.enable | boolean | — | Show 'View All' link (defaults to true if more projects exist than displayed, set to false to explicitly hide) |
archive.link | string | — | Override archive URL (defaults to the first folder in filters.folders) |
archive.text | string | — | Override archive link text (uses i18n 'portfolio_view_all' by default) |
Properties set under the block's design key — shared background, spacing, and color settings apply on top.
| Property | Type | Default | Description |
|---|---|---|---|
columns | 2 | 3 | 4 | 3 | Number of columns (2, 3, or 4) |
fallback_icon | string | code-bracket | Icon to display when no image is provided. Supports all Hugo Blox icon packs: hero (default), brands, devicon, emoji, or custom packs. Format: 'icon-name' or 'pack/icon-name' |
animations | boolean | true | Enable staggered reveal and filter animations |
Compose
Blocks that pair naturally with Portfolio on the same page.
Frequently asked
Ready to build with the Portfolio block?
More blocks like this
Query, filter, sort, and paginate any Markdown content — blog posts, publications, projects — into a styled grid or list.
Drop in long-form prose with polished typography — the escape hatch for anything the structured blocks don't cover.
A dark-mode, developer-focused hero with gradient effects, social links, and call-to-action buttons.
Convert from the first scroll — headline, value prop, dual CTAs, announcement pill, and split-media layouts.