// 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.