PORTO Documentation Live Preview Buy Now

Porto Angular 22 Template Documentation

Porto is a multipurpose, elegant and responsive Angular 22 website template built with Bootstrap 5, SCSS and TypeScript. It suits portfolio landing pages, app landing pages, SaaS and software promotion, digital agencies, startups, business websites and blogs.

Every homepage is assembled from reusable standalone Angular components such as header, banner, about, services, work, pricing, team, testimonials, blog and contact. Content such as text, prices, team members and portfolio items lives in typed data files, so you can turn the demo into your own website without rewriting layout code.

This guide covers installation, project structure, routes, menus, theme colors, the PHP contact form, SEO settings, deployment and the change log. Porto is also available as a NextJS version and a Bootstrap 5 HTML version.

  • Angular 22
  • Bootstrap 5.3
  • SCSS
  • TypeScript

View Live Preview

What's included

15+ homepages

Portfolio, app, SaaS, agency, startup, corporate and parallax layouts, each lazy loaded on its own route.

16+ supportive pages

Six blog layouts, contact, login, register, confirm, lock screen and coming soon pages.

Menu variations

Sticky and normal headers, centered logo, button nav and slide-in sidebar menus.

Lightbox & sorting

PhotoSwipe image lightbox and Shuffle.js category filtering for portfolio galleries.

PHP contact form

A validated Angular form that posts to a bundled PHP mail script.

Modern Angular

Standalone components, no NgModules, zoneless setup, prerendering and Vitest unit tests.

Quick start

npm install
npm start

Open http://localhost:4200/. The full steps are in the Installation section.

Who this guide is for

Developers with basic Angular and npm knowledge who want to install Porto, change its content and colors, and publish it. You do not need to edit component templates to change most text, prices and images.

Requirements

Install these tools before you start.

ToolVersion
Node.js^22.22.3, ^24.15.0 or >=26 (required by Angular 22)
npm8 or newer (the project pins npm 11.13.0 in packageManager)
Angular CLI22.x (also available through npx ng)
PHP hostingOnly needed for the contact form, with mail() enabled

Installation

Get Porto running locally in four steps.

1. Install Angular CLI

npm install -g @angular/cli

2. Open the template folder

cd porto-angular-22

3. Install dependencies

npm install

4. Start the development server

npm start

Open http://localhost:4200/ in your browser. The app reloads automatically whenever you change a source file.

Available scripts

CommandWhat it does
npm startRuns the dev server on port 4200
npm run buildProduction build with prerendered pages in dist/porto-angular-22
npm run build:fileBuild that opens straight from disk (file://) in dist/porto-angular-22-file
npm run watchDevelopment build that rebuilds on every change
npm testRuns unit tests with Vitest

Tip: keep your own changes in the data files and a custom SCSS file so future template updates are easy to merge.

Project Structure

Pages, layout parts and reusable sections are kept in separate folders.

porto-angular-22/
├── public/                     favicon
├── scripts/                    build:file post-processing script
├── src/
│   ├── app/
│   │   ├── core/layout/        headers, sidebars, footers, preloader, scroll to top, page banners
│   │   ├── pages/              one folder per route (index ... index15, blog, login, contact ...)
│   │   ├── shared/
│   │   │   ├── components/     homes, abouts, services, works, pricings, teams, blogs, contact-us ...
│   │   │   ├── directives/     scrollspy, counter, skills, input
│   │   │   ├── models/         seo.json, interfaces, footer link data
│   │   │   ├── services/       SeoService, NavlinkService
│   │   │   └── utils/          animated headlines, velocity typings
│   │   ├── app.config.ts       providers (router, HTTP client, hydration)
│   │   ├── app.routes.ts       all routes (lazy loaded)
│   │   └── app.routes.server.ts prerender settings
│   └── assets/
│       ├── css/                third-party CSS (animate.min.css)
│       ├── fonts/  icons/      icon fonts and font files
│       ├── images/             logos, backgrounds, blog, team, work images
│       ├── php/contact.php    contact form mail script
│       └── scss/               theme, components, sections, shared, pages, plugins
├── angular.json
└── package.json

Pages & Routes

Porto ships with 15 homepages and 16 supportive pages. Each is a standalone component registered in src/app/app.routes.ts and loaded lazily.

Homepages

The empty path redirects to /index, and unknown paths redirect there too.

RouteComponentHeader / menuTheme file
/indexIndexComponentHeader (top nav)theme-1
/index2Index2ComponentHeader 2 (centered logo)theme-2
/index3Index3ComponentHeader 3 + sidebartheme-3
/index4Index4ComponentHeader 2 (centered logo)theme-4
/index5Index5ComponentHeader 3theme-4
/index6Index6ComponentHeader 3app
/index7Index7ComponentSidebar menutheme-3
/index8Index8ComponentApp header + sidebartheme-5
/index9Index9ComponentHeader 3theme-4
/index10Index10ComponentHeader (top nav)theme-1
/index11Index11ComponentHeader 2 (centered logo)theme-2
/index12Index12ComponentHeader 4 (parallax) + sidebarnone
/index13Index13ComponentHeader 3theme-4
/index14Index14ComponentHeader 3 + sidebarapp-2
/index15Index15ComponentHeader (top nav)theme-6

To change the default homepage, edit the redirectTo value of the empty path (and of the ** path) in app.routes.ts.

Supportive pages

RoutePage
/blog-full-pageBlog list, full width
/blog-left-sidebarBlog list with left sidebar
/blog-right-sidebarBlog list with right sidebar
/blog-details-full-width/:idBlog post, full width
/blog-details-left-sidebar/:idBlog post with left sidebar
/blog-details-right-sidebar/:idBlog post with right sidebar
/contact-usContact page with working form
/login, /login2Sign in pages
/register, /register2Sign up pages
/confirmEmail confirmation page
/lockscreen, /lockscreen-2Lock screens
/coming-soon, /coming-soon-2Coming soon pages

Note: the authentication pages are front-end layouts with form validation. Connect them to your own backend before using them in production. The blog :id is the index of the post in BlogList.

Customization

Most content can be changed from data files, images and SCSS, without touching component templates.

Edit content from data files

Each section reads its content from a typed data.ts file next to the section components.

ContentFile
Servicessrc/app/shared/components/services/data.ts
Featuressrc/app/shared/components/features/data.ts
Portfolio / worksrc/app/shared/components/works/data.ts
Pricing planssrc/app/shared/components/pricings/data.ts
Team memberssrc/app/shared/components/teams/data.ts
Testimonialssrc/app/shared/components/testimonials/data.ts
Blog postssrc/app/shared/components/blogs/data.ts
Facts / counterssrc/app/shared/components/facts/data.ts
Contact detailssrc/app/shared/components/contact-us/data.ts
Footer linkssrc/app/shared/models/data.ts

Headings and short intro texts that are not in a data file live in the section component template, for example home1.component.html.

Replace images and logo

  • Images are in src/assets/images (backgrounds in bg, blog posts in blog, work items in works, testimonials in testi).
  • Keep the same file name to replace an image everywhere, or update the path in the matching data file.
  • The header uses two logos: logo.png (white, over banners) and logo-blk.png (dark, on a solid header).
  • Replace public/favicon.ico with your own icon.

Fonts and icons

Fonts (Roboto, Poppins, Barlow, Open Sans and Roboto Slab) are imported from Google Fonts in src/assets/scss/fonts/_fonts.scss. Change the import there, and the font stacks in _variables.scss. Icon fonts are in src/assets/fonts and src/assets/icons, wired up in icons.scss.

Demo images are for preview purposes only. Replace them with your own before publishing.

Theme Colors & SCSS

Colors, fonts and spacing are controlled from a few SCSS files.

Global variables

Edit src/assets/scss/_variables.scss. The main brand color is $theme-color-1 (#3584A7), and the Bootstrap color map (primary, secondary, success and so on) is built from the variables in the same file.

$theme-color-1: #3584A7;
$warning: #fab758;
$success: #45c4a0;

Per-homepage themes

Each homepage loads one theme file from src/assets/scss/themes through styleUrls in its component, for example theme-1.scss for /index. Theme files set CSS custom properties such as --app-theme-color and the gradients used for buttons and overlays.

:root {
  --app-theme-color: #4e5aff;
  --app-btn-gred: linear-gradient(to right, #4e5aff 0%, #800fee 51%, #2540f0 100%);
}

Change the values in the theme file used by the homepage you want to recolor. Because page styles are loaded with ViewEncapsulation.None, theme changes apply to the whole page.

SCSS organization

FolderContents
components/Buttons, forms, modals, pagination, backgrounds, text
sections/Styles for about, services, portfolio, pricing, teams, testimonials, blogs, contact and more
shared/Header, sidebar, footer, preloader, scroll to top, animations
pages/Login, auth, blog, contact and coming soon page styles
plugins/Swiper, Owl Carousel, AOS, PhotoSwipe, parallax and animated headline styles
themes/Color themes used by the homepages

Add a New Page

Create your own page from existing sections in four steps.

Porto pages are standalone components, so a new page only needs a component, a route and an SEO entry. The easiest start is to copy an existing page folder, for example src/app/pages/index10.

  1. Copy the page folder and rename the component, selector and class (for example my-page and MyPageComponent).
  2. Edit the template to keep, remove or reorder section tags, and update the imports array to match.
  3. Register a lazy loaded route in src/app/app.routes.ts, above the ** route:
{
  path: 'my-page',
  loadComponent: () =>
    import('./pages/my-page/my-page.component').then((m) => m.MyPageComponent),
},
  1. Add an entry with the same key (my-page) to seo.json with a title, description and breadcrumb.

Because the build prerenders routes, the new page is generated as static HTML the next time you run npm run build.

Contact Form (PHP)

The contact form posts to a bundled PHP script that validates the fields and sends an email.

The form component (contact-us-form) sends firstName, lastName, email, phone and message to assets/php/contact.php. The script checks the name and email and then calls PHP mail().

Set it up

  1. Open src/assets/php/contact.php.
  2. Set $recipient to your own email address. In the demo it is set to the sender's address, so replace it or you will not receive messages.
  3. Remove or replace the demo address in $bcc.
  4. Deploy the built site to PHP hosting so that assets/php/contact.php is served by PHP.
$recipient = "you@yourdomain.com";
$bcc = "";   // optional

PHP 8 note: the script calls get_magic_quotes_gpc(), which was removed in PHP 8. On PHP 8 or newer, delete that if block (it only calls stripslashes) or the form will fail.

The form does not work from npm start because the Angular dev server does not run PHP. Test it on PHP hosting or a local PHP server.

SEO Settings

Page titles, descriptions and structured data come from a single JSON file.

Edit src/app/shared/models/seo.json. The site block holds the site name, URL, default image and product details. The pages block has a title, description and breadcrumb for each route key (index, index2, contact-us and so on). SeoService applies them to each route, including during prerendering.

Before you publish: change site.siteUrl from https://example.com to your real domain, and update the site name and image.

SEO checklist before launch

  • Write a unique title (about 50 to 60 characters) and description (about 150 to 160 characters) for every route in seo.json.
  • Replace demo images and give every image a descriptive alt text.
  • Keep one h1 per page and use headings in order.
  • Add a robots.txt and a sitemap.xml to the public folder so they are copied into the build output.
  • Serve the site over HTTPS and submit the sitemap in Google Search Console.

Browser Support

Porto is responsive and works across modern browsers and mobile devices.

Angular 22 targets the current versions of Chrome, Edge, Firefox and Safari, on desktop as well as on iOS and Android. Older browsers that do not support modern JavaScript features are not supported. Layouts use the Bootstrap 5 grid, so pages adapt to phones, tablets and desktops without extra setup.

Some animations (AOS scroll effects) are switched off on tablet and smaller screens by design, which keeps scrolling smooth on mobile devices.

Dependencies

Everything is installed with npm install.

Packages

PackagePurpose
@angular/* 22Framework, router, forms, SSR and prerendering
bootstrap, @popperjs/core, @ng-bootstrap/ng-bootstrapGrid, components, collapse and modals
swiper, ngx-owl-carousel-oSliders and carousels
photoswipe, shufflejsImage lightbox and portfolio sorting
aos, typed.js, velocity-animate, vivusScroll animations, typed text, animated headlines and SVG drawing
jarallax, parallax-js, ngx-smooth-parallaxParallax backgrounds
ng-particles, tsparticles, tsparticles-engineAnimated particle banners
ngx-page-scrollSmooth scrolling to sections
rxjs, tslibReactive utilities and TypeScript helpers

Dev packages

  • @angular/cli, @angular/build, @angular/compiler-cli: build tooling
  • typescript 6, vitest, jsdom: language and unit tests
  • prettier: code formatting (see .prettierrc)

Security audit (known vulnerabilities)

Last checked with npm audit on October 19, 2026, across 500 installed packages (164 production, 336 development). No known vulnerabilities were reported.

Levelnpm severityFound
MajorCritical and high0
MinorModerate0
LowLow and info0

New advisories are published over time, so run the audit yourself before you deploy:

npm audit
npm audit fix

Note: avoid npm audit fix --force. It can install breaking major versions of Angular or other packages.

Build & Deploy

Create an optimized build and upload it to any static host.

npm run build

The production build prerenders every route, including each blog post, so the output in dist/porto-angular-22/browser is plain static files that work on any web host.

Hosting options

  • Static hosting: upload the contents of dist/porto-angular-22/browser to Netlify, Vercel, GitHub Pages, S3 or a shared host.
  • PHP hosting: use the same upload if you want the contact form to work.
  • Open from disk: npm run build:file creates a build in dist/porto-angular-22-file/browser that opens by double-clicking index.html. It uses hash URLs (for example index.html#/index2).

Server rewrite rule

If you deploy without prerendered files, send unknown paths to index.html. Nginx example:

location / {
  try_files $uri $uri/ /index.html;
}

Testing

npm test

Unit tests run with Vitest through the Angular CLI.

Troubleshooting

Fixes for the most common problems.

npm install fails or the build errors out

Check node -v against the versions in Requirements. Delete node_modules and package-lock.json only as a last resort, then run npm install again.

Port 4200 is already in use

npm start -- --port 4300

Page shows 404 after refresh on the live site

Upload the full contents of the browser folder, including the prerendered route folders, or add the server rewrite rule from Build & Deploy.

Contact form shows an error or nothing happens

Make sure the site is on PHP hosting with mail() enabled, set $recipient, and on PHP 8 remove the get_magic_quotes_gpc() block. See Contact Form (PHP).

Changes to SCSS variables do not appear

Restart npm start. If a homepage still shows old colors, check the theme file that page loads in its styleUrls, since theme files override global variables.

Images are not showing

Image paths are relative to src/assets. Check the spelling and letter case of the file name and path.

FAQ

Which Node.js version does Porto need?

Porto uses Angular 22, which requires Node.js ^22.22.3, ^24.15.0 or >=26 with npm 8 or newer.

How do I change the theme colors?

Edit the brand variables in src/assets/scss/_variables.scss, and the CSS custom properties in the theme file a homepage loads (src/assets/scss/themes). Then restart the dev server.

How do I edit services, pricing, team and portfolio content?

Each section reads its content from a typed data.ts file inside src/app/shared/components, so you can change text, prices and images without touching the templates.

How do I make the contact form send email to me?

Open src/assets/php/contact.php, set $recipient to your email address, and deploy the site to PHP hosting with mail() enabled. On PHP 8 remove the get_magic_quotes_gpc() block.

How do I fix 404 errors after refreshing the live site?

Upload the full contents of dist/porto-angular-22/browser including the prerendered folders, or configure your server to serve index.html for unknown paths, for example try_files $uri $uri/ /index.html in Nginx.

How do I add a new page?

Copy an existing folder in src/app/pages, register a lazy loaded route in app.routes.ts and add an entry with the same key to seo.json. See the Add a New Page section.

Does Porto work with server side rendering?

Yes. The production build prerenders every route, including each blog post, and the project includes the Angular SSR packages and a serve:ssr:porto-angular-22 script.

How do I change the logo and favicon?

Replace logo.png and logo-blk.png in src/assets/images and the favicon.ico in the public folder, keeping the same file names.

Is Porto available for NextJS or plain Bootstrap?

Yes. See the NextJS version at https://lettstartdesign.com/theme/porto-react-nextjs-website-templates and the Bootstrap 5 version at https://lettstartdesign.com/theme/porto-bootstrap-website-templates.

Change Log

Version 1.0.0

Added

  • Angular 22 release with Bootstrap 5.3, SCSS and TypeScript 6
  • Standalone components with lazy loaded routes, no NgModules
  • Prerendering of all routes and blog posts
  • Central SEO configuration in seo.json

Credits

Porto uses these open source libraries.

  • Angular, Bootstrap, ng-bootstrap, Popper
  • Swiper, ngx-owl-carousel-o, PhotoSwipe, Shuffle.js
  • AOS, Typed.js, Velocity, Vivus, Jarallax, parallax.js, tsParticles
  • Google Fonts: Roboto, Poppins, Barlow, Open Sans, Roboto Slab

Demo images are for preview purposes only. Replace them with your own before publishing.

Support

Need help with Porto? Start here before you get in touch.

Check the troubleshooting and FAQ sections first. Your purchase includes one year of free premium support and unlimited updates. Contact LettstartDesign through the support link on your purchase page, and include your template version and a short description of the issue.