// src/app/pages/products/[id].page.ts
import { Component } from '@angular/core';
import { injectLoad } from '@analogjs/router';
import type { load } from './[id].server';
@Component({
template: `
<h1>{{ product().name }}</h1>
<p>{{ product().price | currency }}</p>
`,
})
export default class ProductPage {
protected readonly product = injectLoad<typeof load>();
} The fullstack
Angular meta-framework
Vite-based. File-based routing. API routes. SSR and SSG. Everything you need to build modern Angular apps and sites.
$ vite buildvite building client environment for production...vite building ssr environment for production...transforming...✓ 325 modules transformed.rendering chunks...✓ 985 modules transformed.computing gzip size...dist/client/index.html 1.42 kB │ gzip: 0.71 kBdist/client/assets/styles-DG3kLxYZ.css 8.74 kB │ gzip: 2.31 kBdist/client/assets/router-Bs1mQ2Dn.js 18.55 kB │ gzip: 6.84 kBdist/client/assets/content-BMF8KG2I.js 59.86 kB │ gzip: 5.31 kBdist/client/assets/(home).page-CKxFXlHY.js 21.67 kB │ gzip: 5.60 kBdist/client/assets/docs.page-DdVccY_7.js 1.65 kB │ gzip: 0.82 kBdist/client/assets/__...slug__.page-BL_P3rL8.js 22.80 kB │ gzip: 6.86 kBdist/client/assets/SidebarDrawer-CauwW0x6.js 10.26 kB │ gzip: 2.94 kBdist/client/assets/index-CVGT2tp1.js 366.98 kB │ gzip: 98.56 kBdist/ssr/assets/__...slug__.page-DtcjJoL6.mjs 0.08 kB │ gzip: 0.09 kBdist/ssr/assets/overview-BdZizd5o2.mjs 0.33 kB │ gzip: 0.24 kBdist/ssr/assets/overview-gxyYn8v8.mjs 0.34 kB │ gzip: 0.26 kBdist/ssr/assets/contributing-B83XZww7.mjs 0.35 kB │ gzip: 0.24 kBdist/ssr/assets/overview-CQRmUDJ9.mjs 0.35 kB │ gzip: 0.26 kBdist/ssr/assets/support-DLAA5sQ1.mjs 1.46 kB │ gzip: 0.74 kBdist/ssr/assets/compatibility-BZp34UUz.mjs 1.58 kB │ gzip: 0.73 kBdist/ssr/assets/docs.page-DdVccY_7.mjs 1.65 kB │ gzip: 0.82 kBdist/ssr/assets/introduction-N_pq0X4B.mjs 1.66 kB │ gzip: 0.88 kBdist/ssr/assets/sponsoring-B3SIcVC_.mjs 3.26 kB │ gzip: 1.44 kBdist/ssr/assets/ai-CM8fF-iZ.mjs 3.37 kB │ gzip: 1.58 kBdist/ssr/assets/code-generation-D3nEY0Jc.mjs 3.46 kB │ gzip: 0.91 kBdist/ssr/assets/getting-started-BBfHjgQX.mjs 4.35 kB │ gzip: 1.19 kBdist/ssr/assets/sidebar-0YQ3z2x-.mjs 5.00 kB │ gzip: 1.27 kBdist/ssr/assets/nx-BNqm_DkJ.mjs 5.02 kB │ gzip: 1.63 kBdist/ssr/assets/overview-44-GjfuI.mjs 6.48 kB │ gzip: 2.29 kBdist/ssr/assets/css-preprocessors-CQfu_AHS.mjs 8.38 kB │ gzip: 1.26 kBdist/ssr/assets/server-side-data-fetching-Cfucm9Ra.mjs 9.50 kB │ gzip: 1.60 kBdist/ssr/assets/SidebarDrawer-CauwW0x6.mjs 10.26 kB │ gzip: 2.94 kBdist/ssr/assets/middleware-C797dNXV.mjs 10.60 kB │ gzip: 1.44 kBdist/ssr/assets/migrating-hJYmSKgU.mjs 11.88 kB │ gzip: 1.54 kBdist/ssr/assets/contributing-XmnAkxCh.mjs 14.82 kB │ gzip: 3.31 kBdist/ssr/assets/og-image-generation-DxcxVtL1.mjs 15.48 kB │ gzip: 2.35 kBdist/ssr/assets/server-side-rendering-C01L6B-f.mjs 17.74 kB │ gzip: 2.03 kBdist/ssr/assets/angular-material-i01XyO0x.mjs 18.14 kB │ gzip: 2.48 kBdist/ssr/assets/(home).page-CKxFXlHY.mjs 21.67 kB │ gzip: 5.60 kBdist/ssr/assets/__...slug__.page-BL_P3rL8.mjs 22.80 kB │ gzip: 6.86 kBdist/ssr/assets/metadata-C5mGU_4S.mjs 22.59 kB │ gzip: 2.38 kBdist/ssr/assets/websockets-fkNokGag.mjs 25.44 kB │ gzip: 2.46 kBdist/ssr/assets/libraries-BouNIxxQ.mjs 28.63 kB │ gzip: 2.94 kBdist/ssr/assets/migrating-7oCQdL3T.mjs 31.68 kB │ gzip: 3.39 kBdist/ssr/assets/forms-CNTfSCaP.mjs 37.20 kB │ gzip: 3.53 kBdist/ssr/assets/vitest-Ct7_OCIH.mjs 41.57 kB │ gzip: 4.03 kBdist/ssr/assets/providers-CWTrAY_M.mjs 47.16 kB │ gzip: 7.26 kBdist/ssr/assets/ionic-BwIlEq-c.mjs 51.91 kB │ gzip: 5.77 kBdist/ssr/assets/static-site-generation-C5zOsHes.mjs 58.21 kB │ gzip: 4.62 kBdist/ssr/assets/contributors-BZhKJ-kP.mjs 58.87 kB │ gzip: 7.22 kBdist/ssr/assets/storybook-BmH4JEXl.mjs 59.04 kB │ gzip: 4.96 kBdist/ssr/assets/content-CpCKBY6T.mjs 62.11 kB │ gzip: 5.44 kBdist/ssr/assets/providers-BB74njZp.mjs 71.76 kB │ gzip: 9.19 kBdist/ssr/assets/content-2qeL0Vxi.mjs 76.30 kB │ gzip: 6.34 kBdist/ssr/assets/static-site-generation-AUywW2Um.mjs 80.39 kB │ gzip: 5.36 kBdist/ssr/main.server.mjs 130.82 kB │ gzip: 26.11 kB✓ built in 7.66s▍Routing
Filesystem-based routing
Files in src/app/pages/ become routes. Brackets are dynamic. Double brackets are catch-alls. Parentheses are pathless groups.
No route config file. No registration step. Add a file, ship a page.
src/app/pages/
- (home).page.ts
- about.page.ts
- docs/[[...slug]].page.ts
- products/[id].page.ts
- api/og.ts
generated routes
- /
- /about
- /docs/*
- /products/:id
- /api/og
Fullstack
Client and server, one file pair
Co-locate a server loader next to the page component. Analog runs it on the server, ships only the response to the client, and types the response end-to-end.
The page imports the load type — no separate API client, no manual fetch.
// src/app/pages/products/[id].server.ts
import type { PageServerLoad } from '@analogjs/router';
import { db } from '~/server/db';
export const load = async ({
params,
}: PageServerLoad) => {
const product = await db.products.byId(
params['id'],
);
return product;
};Ecosystem
The Vite ecosystem, in Angular
Analog plugs into the tools your team already trusts. No fork, no shim — the same plugins, the same configuration.
Analog is free, open source, and supported by our partners and sponsors.