<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Analog</title>
    <description>The latest articles on Forem by Analog (@analogjs).</description>
    <link>https://forem.com/analogjs</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F6873%2Fb92c314c-e0f6-4dd8-a095-2df05490adb1.png</url>
      <title>Forem: Analog</title>
      <link>https://forem.com/analogjs</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/analogjs"/>
    <language>en</language>
    <item>
      <title>AnalogJS 2.4: Vite 8, Vitest Snapshot Serializers, Astro v6 Support, and more!</title>
      <dc:creator>Brandon Roberts</dc:creator>
      <pubDate>Mon, 30 Mar 2026 16:52:55 +0000</pubDate>
      <link>https://forem.com/analogjs/analogjs-24-vite-8-vitest-snapshot-serializers-astro-v6-support-and-more-3hgo</link>
      <guid>https://forem.com/analogjs/analogjs-24-vite-8-vitest-snapshot-serializers-astro-v6-support-and-more-3hgo</guid>
      <description>&lt;p&gt;We are excited to announce the release of Analog 2.4! This release brings Vite 8 support, significant testing improvements for Vitest w/ Angular, and an updated Astro Angular integration. Let's dive in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vite 8 Support ⚡️
&lt;/h2&gt;

&lt;p&gt;Analog 2.4 updates to the stable release of Vite 8.0.0. This is a major ecosystem alignment that brings several benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rolldown bundler&lt;/strong&gt;: Vite 8 introduces Rolldown, a Rust-based bundler, as an alternative to esbuild for optimization. Analog's Angular Vite plugin now detects Rolldown availability and uses OXC-based compilation when available.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vite Environment API&lt;/strong&gt;: Analog leverages the new Environment API for managing client and server configurations, particularly in the Astro Angular integration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backward compatibility&lt;/strong&gt;: Analog integrations continue to support Vite 5 through 8, so you can upgrade at your own pace.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Vitest DX Improvements 🧪
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Reusable Snapshot Serializers
&lt;/h3&gt;

&lt;p&gt;Writing snapshot tests for Angular components often produces noisy output filled with framework internals like &lt;code&gt;_ngcontent-*&lt;/code&gt;, &lt;code&gt;_nghost-*&lt;/code&gt;, &lt;code&gt;ng-reflect-*&lt;/code&gt; attributes, and &lt;code&gt;&amp;lt;!--container--&amp;gt;&lt;/code&gt; comments. Analog 2.4 introduces three built-in snapshot serializers that clean this up.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;createNoNgAttributesSnapshotSerializer&lt;/code&gt;&lt;/strong&gt; strips Angular runtime noise from DOM snapshots. Here's what that looks like in practice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Before --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"root0"&lt;/span&gt; &lt;span class="na"&gt;ng-version=&lt;/span&gt;&lt;span class="s"&gt;"21.1.3"&lt;/span&gt; &lt;span class="na"&gt;_nghost-a-c1=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card ng-star-inserted keep-me"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card ng-star-inserted"&lt;/span&gt; &lt;span class="na"&gt;_ngcontent-a-c1=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;ng-reflect-foo=&lt;/span&gt;&lt;span class="s"&gt;"bar"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Title&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- After --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card keep-me"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Title&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;createAngularFixtureSnapshotSerializer&lt;/code&gt;&lt;/strong&gt; converts &lt;code&gt;ComponentFixture&lt;/code&gt; objects into clean component markup, so instead of seeing raw testing internals you get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;app-chip&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;
    Hello [Input Signal: Alice]
  &lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/app-chip&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;createHtmlCommentSnapshotSerializer&lt;/code&gt;&lt;/strong&gt; removes Angular-generated HTML comments like &lt;code&gt;&amp;lt;!--container--&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The easiest way to enable all serializers is via the automatic setup imports in your test setup file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/compiler&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@analogjs/vitest-angular/setup-snapshots&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@analogjs/vitest-angular/setup-serializers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;setupTestBed&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@analogjs/vitest-angular/setup-testbed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;setupTestBed&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;New Analog projects include this by default. You can also register serializers individually if you need more control:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;createAngularFixtureSnapshotSerializer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;createNoNgAttributesSnapshotSerializer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;createHtmlCommentSnapshotSerializer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@analogjs/vitest-angular/snapshot-serializers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addSnapshotSerializer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;createAngularFixtureSnapshotSerializer&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addSnapshotSerializer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;createNoNgAttributesSnapshotSerializer&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addSnapshotSerializer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;createHtmlCommentSnapshotSerializer&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Many thanks to &lt;a href="https://x.com/tim_deschryver" rel="noopener noreferrer"&gt;Tim Deschryver&lt;/a&gt; for adding this feature!&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;teardown.destroyAfterEach&lt;/code&gt; Option
&lt;/h3&gt;

&lt;p&gt;The new &lt;code&gt;teardown&lt;/code&gt; option on &lt;code&gt;setupTestBed&lt;/code&gt; gives you explicit control over Angular TestBed cleanup behavior:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;setupTestBed&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@analogjs/vitest-angular/setup-testbed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;setupTestBed&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;teardown&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;destroyAfterEach&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This replaces the &lt;code&gt;browserMode&lt;/code&gt; option, which is now deprecated and will be removed in v3.0.0.&lt;/p&gt;

&lt;p&gt;Check out our &lt;a href="https://analogjs.org/docs/features/testing/vitest" rel="noopener noreferrer"&gt;Vitest Guide&lt;/a&gt; for more information on setting up Vitest in your Angular projects.&lt;/p&gt;

&lt;p&gt;Many thanks to &lt;a href="https://x.com/yjaaidi" rel="noopener noreferrer"&gt;Younes Jaaidi&lt;/a&gt; for adding this feature!&lt;/p&gt;

&lt;h2&gt;
  
  
  Astro v6 Support &amp;amp; Strict Style Placement 🚀
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Astro v6 Compatibility
&lt;/h3&gt;

&lt;p&gt;Analog 2.4 adds full support for Astro v6 via the new Vite Environment API. Use the official Astro upgrade tool to update Astro and its integrations together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @astrojs/upgrade
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then update &lt;code&gt;@analogjs/astro-angular&lt;/code&gt; to the latest version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @analogjs/astro-angular@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;strictStylePlacement&lt;/code&gt; Option
&lt;/h3&gt;

&lt;p&gt;A new &lt;code&gt;strictStylePlacement&lt;/code&gt; configuration option moves Angular component styles from the component body into the document &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;, producing valid HTML output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// astro.config.mjs&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;astro/config&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;angular&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@analogjs/astro-angular&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;integrations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;angular&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;strictStylePlacement&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;})],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When enabled, Angular component styles are relocated to &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; regardless of which island they originate from. Style ordering is preserved across multiple islands, and styles inside &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt; elements (shadow DOM) are left in place. This lays the foundation for enabling client-side hydration of Angular components when used with Astro.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Enabling this option disables Astro's streaming mode under SSR.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Many thanks to &lt;a href="https://github.com/eblocha" rel="noopener noreferrer"&gt;eblocha&lt;/a&gt; for the feature request and addition!&lt;/p&gt;

&lt;h2&gt;
  
  
  Upgrading
&lt;/h2&gt;

&lt;p&gt;To upgrade to Analog 2.4, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng update @analogjs/platform@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're using Nx, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nx migrate @analogjs/platform@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the full list of changes, see the &lt;a href="https://github.com/analogjs/analog/blob/main/CHANGELOG.md" rel="noopener noreferrer"&gt;changelog&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Partner with Analog 🤝
&lt;/h2&gt;

&lt;p&gt;Continued development of Analog would not be possible without our partners and community. Thanks to our official deployment partner &lt;a href="https://zerops.io" rel="noopener noreferrer"&gt;Zerops&lt;/a&gt;, code review partner &lt;a href="https://coderabbit.link/analogjs" rel="noopener noreferrer"&gt;CodeRabbit&lt;/a&gt;, and longtime supporters &lt;a href="https://snyder.tech/" rel="noopener noreferrer"&gt;Snyder Technologies&lt;/a&gt;, &lt;a href="https://nx.dev" rel="noopener noreferrer"&gt;Nx&lt;/a&gt;, and &lt;a href="https://houseofangular.io" rel="noopener noreferrer"&gt;House of Angular&lt;/a&gt;, and many other backers of the project.&lt;/p&gt;

&lt;p&gt;Find out more information on our &lt;a href="https://analogjs.org/docs/sponsoring#partnerships" rel="noopener noreferrer"&gt;partnership opportunities&lt;/a&gt; or reach out directly to partnerships[at]analogjs.org.&lt;/p&gt;

&lt;h2&gt;
  
  
  Join the Community 🥇
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Visit and Star the &lt;a href="https://github.com/analogjs/analog" rel="noopener noreferrer"&gt;GitHub Repo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Join the &lt;a href="https://chat.analogjs.org" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Follow us on &lt;a href="https://twitter.com/analogjs" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you enjoyed this post, click the ❤️ so other people will see it. Follow &lt;a href="https://twitter.com/analogjs" rel="noopener noreferrer"&gt;AnalogJS&lt;/a&gt; and &lt;a href="https://bsky.app/profile/brandonroberts.dev" rel="noopener noreferrer"&gt;Brandon Roberts&lt;/a&gt; on Bluesky, and subscribe to my &lt;a href="https://youtube.com/brandonrobertsdev?sub_confirmation=1" rel="noopener noreferrer"&gt;YouTube Channel&lt;/a&gt; for more content!&lt;/p&gt;

</description>
      <category>angular</category>
    </item>
    <item>
      <title>Announcing AnalogJS 2.0 ⚡️</title>
      <dc:creator>Brandon Roberts</dc:creator>
      <pubDate>Mon, 03 Nov 2025 15:20:19 +0000</pubDate>
      <link>https://forem.com/analogjs/announcing-analogjs-20-348d</link>
      <guid>https://forem.com/analogjs/announcing-analogjs-20-348d</guid>
      <description>&lt;p&gt;We're excited to announce the 2.0 release of AnalogJS! This release includes many features that help developers ship websites and applications, faster, with Angular.&lt;/p&gt;

&lt;p&gt;This release marks the second major release of Analog, providing developers many new features and improvements to build with Analog. &lt;/p&gt;

&lt;h2&gt;
  
  
  Features ⭐️
&lt;/h2&gt;

&lt;p&gt;Analog is the meta-framework built on top of Angular, powered by &lt;a href="https://vitejs.dev" rel="noopener noreferrer"&gt;Vite&lt;/a&gt;, a next generation open-source build tool, and &lt;a href="https://nitro.unjs.io" rel="noopener noreferrer"&gt;Nitro&lt;/a&gt;, an open-source server engine framework. Here are some of its features, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First-class support for the Vite ecosystem (Vitest, Playwright, Storybook, and more)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://analogjs.org/docs/features/routing/overview" rel="noopener noreferrer"&gt;Filesystem-based routing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://analogjs.org/docs/features/routing/content" rel="noopener noreferrer"&gt;Support for markdown&lt;/a&gt; pages and blogs &lt;/li&gt;
&lt;li&gt;&lt;a href="https://analogjs.org/docs/features/api/overview" rel="noopener noreferrer"&gt;Support for API/server routes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Hybrid &lt;a href="https://analogjs.org/docs/features/server/server-side-rendering" rel="noopener noreferrer"&gt;SSR&lt;/a&gt;/&lt;a href="https://analogjs.org/docs/features/server/static-site-generation" rel="noopener noreferrer"&gt;SSG&lt;/a&gt; with sitemap and RSS feed support&lt;/li&gt;
&lt;li&gt;Supports Angular CLI/&lt;a href="https://analogjs.org/docs/integrations/nx" rel="noopener noreferrer"&gt;Nx workspaces&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Server and deployment support&lt;/li&gt;
&lt;li&gt;And more!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What's New
&lt;/h2&gt;

&lt;p&gt;Analog 2.0 contains many new features including content resources, smaller install and bundle size optimizations, and Vite ecosystem upgrades.&lt;/p&gt;

&lt;h3&gt;
  
  
  Content Resources 📜
&lt;/h3&gt;

&lt;p&gt;As Angular continues to evolve with the introduction of Resources, Analog now also includes resources for displaying content lists and content files.&lt;/p&gt;

&lt;p&gt;Content Files resources are used to display lists of loaded content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;contentFilesResource&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@analogjs/content/resources&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;PostsComponent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../components/posts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../data/posts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blog-posts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Posts&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    @defer(hydrate on hover) {
      &amp;lt;posts [posts]="postsResource.value()"&amp;gt;&amp;lt;/posts&amp;gt;
    }
  `&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Blog&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;postsResource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;contentFilesResource&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Post&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Content file resources retrieve content as a signal, integrating with Angular's latest primitives for reactivity.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;MarkdownComponent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@analogjs/content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;contentFileResource&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@analogjs/content/resources&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;RouteMeta&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@analogjs/router&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../data/posts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;postMetaResolver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;postTitleResolver&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./resolvers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;routeMeta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;RouteMeta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;postTitleResolver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;postMetaResolver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;post&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;MarkdownComponent&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    @let post = postResource.value();

    @if (post) {
      &amp;lt;div class="flex flex-grow justify-center min-h-screen"&amp;gt;
        &amp;lt;article class="w-screen max-w-4xl p-8"&amp;gt;
          &amp;lt;h2 class="text-gray-600 text-2xl"&amp;gt;{{ post.attributes.title }}&amp;lt;/h2&amp;gt;

          &amp;lt;span class="font-light text-sm"&amp;gt;
            {{ post.attributes.publishedDate }} -
            {{ post.content }} min read
          &amp;lt;/span&amp;gt;

          &amp;lt;analog-markdown [content]="post.content"&amp;gt;&amp;lt;/analog-markdown&amp;gt;
        &amp;lt;/article&amp;gt;
      &amp;lt;/div&amp;gt;
    }
  `&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BlogPost&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;postResource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;contentFileResource&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Post&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As Resources are still experimental in Angular, there will be future updates, and we're looking to further support these new APIs in Analog.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installation and Bundle Size Optimizations 📦
&lt;/h3&gt;

&lt;p&gt;We've continued to improve Analog projects, including installing project dependencies and optimizing bundle sizes. A few changes include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Smaller install footprint for Angular CLI workspaces without any Webpack dependencies.&lt;/li&gt;
&lt;li&gt;All Angular builders are shipped as ESM.&lt;/li&gt;
&lt;li&gt;Replacing packages with smaller equivalents, such as using &lt;code&gt;tinyglobby&lt;/code&gt; instead of &lt;code&gt;fast-glob&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Direct usage of the Vite CLI for serve/build in addition to &lt;code&gt;ng serve&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Direct usage of the Vitest CLI for testing in addition to &lt;code&gt;ng test&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Generated bundle output size reduction of 100Kb+ for full-stack projects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These optimizations decrease the installation time of Analog projects in development, and reduce the amount of code built and shipped.&lt;/p&gt;

&lt;h3&gt;
  
  
  Vite Ecosystem Upgrades ⚡️
&lt;/h3&gt;

&lt;p&gt;Analog continues to integrate and support many Vite ecosystem integrations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Angular v17-v20 with upcoming support for Angular v21&lt;/li&gt;
&lt;li&gt;Vite 6.x and 7.x, including support for the latest Rolldown-Vite releases&lt;/li&gt;
&lt;li&gt;Vitest 3.x and 4.x including support for the Vitest VSCode extension&lt;/li&gt;
&lt;li&gt;Nx 22.x&lt;/li&gt;
&lt;li&gt;Storybook 10.x, including support for &lt;a href="https://github.com/brandonroberts/angular-vite-storybook/pull/21/files" rel="noopener noreferrer"&gt;component testing with Vitest&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Astro 5.x&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Angular support for Vitest 🧪
&lt;/h3&gt;

&lt;p&gt;In Angular v21, stable support for Vitest directly through the Angular CLI was introduced for new Angular projects. While both Analog and Angular support running tests with Vitest, there are some similarities and key differences.&lt;/p&gt;

&lt;p&gt;The table below shows the features available across both choices.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Vitest&lt;/th&gt;
&lt;th&gt;Analog&lt;/th&gt;
&lt;th&gt;Angular&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Angular Versions&lt;/td&gt;
&lt;td&gt;v17+&lt;/td&gt;
&lt;td&gt;v21+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vitest Versions&lt;/td&gt;
&lt;td&gt;2.0+&lt;/td&gt;
&lt;td&gt;4.0+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Support&lt;/td&gt;
&lt;td&gt;Community&lt;/td&gt;
&lt;td&gt;Angular Team&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Builders&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Schematics&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Migrations&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fully Configurable&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;⚠️&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vitest CLI&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vitest Workpsaces&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Custom Environments&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Custom Providers&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IDE extensions&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Buildable Libs&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Module Mocking/Graph&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Plugins/Types&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The table above is not to compare the two solutions, but to provide the information on what features are supported by each implementation. Choose the solution that best fits your needs and priorities.&lt;/p&gt;

&lt;p&gt;Check out our guide on how you can &lt;a href="https://analogjs.org/docs/features/testing/vitest" rel="noopener noreferrer"&gt;add Vitest&lt;/a&gt; to any existing Angular project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contributions and Community 🤓
&lt;/h2&gt;

&lt;p&gt;AnalogJS would not be where it is without a team of core contributors and collaborators.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/goetzrobin" rel="noopener noreferrer"&gt;Robin Goetz&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/markostdev" rel="noopener noreferrer"&gt;Marko Stanimirović&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/LuisHCCDev" rel="noopener noreferrer"&gt;Luis Castro&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/nartc1410" rel="noopener noreferrer"&gt;Chau Tran&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/joshuamorony" rel="noopener noreferrer"&gt;Joshua Morony&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/villanuevand" rel="noopener noreferrer"&gt;Andrés Villanueva&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, thanks to the &lt;a href="https://github.com/analogjs/analog#contributors-" rel="noopener noreferrer"&gt;150+ contributors&lt;/a&gt; to the project, whether through code, documentation, tests, or even just trying out the project. &lt;/p&gt;

&lt;p&gt;The project already has nearly 3000 stars on &lt;a href="https://github.com/analogjs/analog" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;, 1000+ members on &lt;a href="https://chat.analogjs.org" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;, 1000+ followers on &lt;a href="https://twitter.com/analogjs" rel="noopener noreferrer"&gt;Twitter/X&lt;/a&gt;, and was accepted into the first &lt;a href="https://accelerator.github.com/" rel="noopener noreferrer"&gt;GitHub Accelerator Cohort&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Partner with Analog 🤝
&lt;/h2&gt;

&lt;p&gt;Continued development of Analog would not be possible without our partners and community. Thanks to our official deployment partner &lt;a href="https://zerops.io" rel="noopener noreferrer"&gt;Zerops&lt;/a&gt; and longtime supporters &lt;a href="https://snyder.tech/" rel="noopener noreferrer"&gt;Snyder Technologies&lt;/a&gt;, &lt;a href="https://nx.dev" rel="noopener noreferrer"&gt;Nx&lt;/a&gt;, and &lt;a href="https://houseofangular.io" rel="noopener noreferrer"&gt;House of Angular&lt;/a&gt;, and many other backers of the project.&lt;/p&gt;

&lt;p&gt;Find out more information on our &lt;a href="https://analogjs.org/docs/sponsoring#partnerships" rel="noopener noreferrer"&gt;partnership opportunities&lt;/a&gt; or reach out directly to partnerships[at]analogjs.org. &lt;/p&gt;

&lt;h2&gt;
  
  
  Join the Community 🥇
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Visit and Star the &lt;a href="https://github.com/analogjs/analog" rel="noopener noreferrer"&gt;GitHub Repo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Join the &lt;a href="https://chat.analogjs.org" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Follow us on &lt;a href="https://twitter.com/analogjs" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you enjoyed this post, click the ❤️ so other people will see it. Follow &lt;a href="https://twitter.com/analogjs" rel="noopener noreferrer"&gt;AnalogJS&lt;/a&gt; and &lt;a href="https://twitter.com/brandontroberts" rel="noopener noreferrer"&gt;me&lt;/a&gt; on Twitter/X, and subscribe to my &lt;a href="https://youtube.com/brandonrobertsdev?sub_confirmation=1" rel="noopener noreferrer"&gt;YouTube Channel&lt;/a&gt; for more content!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>angular</category>
    </item>
    <item>
      <title>AnalogJS 🤝 Zerops: Official Deployment Partners</title>
      <dc:creator>Brandon Roberts</dc:creator>
      <pubDate>Tue, 15 Oct 2024 17:54:46 +0000</pubDate>
      <link>https://forem.com/analogjs/analogjs-zerops-official-deployment-partners-1ml0</link>
      <guid>https://forem.com/analogjs/analogjs-zerops-official-deployment-partners-1ml0</guid>
      <description>&lt;p&gt;We're super excited to announce &lt;a href="https://zerops.io?utm_medium=blog" rel="noopener noreferrer"&gt;Zerops&lt;/a&gt; as the Official Deployment Partner for Analog.&lt;/p&gt;

&lt;p&gt;This new partnership guarantees more features, support, collaboration, and an improved experience for deploying not only fullstack applications with AnalogJS and Angular, but scalable solutions including databases, Content Management Systems, full Linux containers, and more.&lt;/p&gt;

&lt;p&gt;Zerops is a Dev-first cloud platform that builds, deploys, runs and manages apps, no matter the size or environment. &lt;a href="https://zerops.io/?utm_medium=blog#pricing" rel="noopener noreferrer"&gt;Zerops&lt;/a&gt; is free to get started, along with transparent and upfront pricing. On a personal note, Zerops is also built using Angular, and we've long stated that when &lt;a href="https://zerops.io/article/why-we-became-analog-s-deployment-partner" rel="noopener noreferrer"&gt;finding a partnership opportunity&lt;/a&gt;, we wanted someone willing to continue to invest in Angular and its ecosystem of OSS projects.&lt;/p&gt;

&lt;p&gt;AnalogJS ❤️ Zerops&lt;/p&gt;

&lt;p&gt;Analog is excited to have &lt;a href="https://zerops.io?utm_medium=blog" rel="noopener noreferrer"&gt;Zerops&lt;/a&gt; as our new official deployment partner. We are thankful for the trust and support of the entire Zerops team. Because of their support, in addition to our other sponsors, &lt;a href="https://snyder.tech" rel="noopener noreferrer"&gt;SnyderTech&lt;/a&gt;, &lt;a href="https://code.build" rel="noopener noreferrer"&gt;Jonathan Gamble&lt;/a&gt;, and &lt;a href="https://nx.dev" rel="noopener noreferrer"&gt;Nx&lt;/a&gt; that we are able to receive ongoing maintenance and keep developing Analog for the long term in a financially sustainable way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Partner with Analog 🤝
&lt;/h2&gt;

&lt;p&gt;Find out more information on our other &lt;a href="https://github.com/sponsors/brandonroberts" rel="noopener noreferrer"&gt;partnership opportunities&lt;/a&gt; or reach out directly to partnerships[at]analogjs.org. &lt;/p&gt;

&lt;h2&gt;
  
  
  Join the Community 🥇
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Visit and Star the &lt;a href="https://github.com/analogjs/analog" rel="noopener noreferrer"&gt;GitHub Repo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Join the &lt;a href="https://chat.analogjs.org" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Follow us on &lt;a href="https://twitter.com/analogjs" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you enjoyed this post, click the ❤️ so other people will see it. Follow &lt;a href="https://twitter.com/analogjs" rel="noopener noreferrer"&gt;AnalogJS&lt;/a&gt; and &lt;a href="https://twitter.com/brandontroberts" rel="noopener noreferrer"&gt;me&lt;/a&gt; on Twitter/X&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>angular</category>
      <category>devops</category>
    </item>
    <item>
      <title>Bridging Analog to Angular with esbuild and Vite</title>
      <dc:creator>Brandon Roberts</dc:creator>
      <pubDate>Thu, 11 Apr 2024 15:07:00 +0000</pubDate>
      <link>https://forem.com/analogjs/bridging-analog-to-angular-with-esbuild-and-vite-472j</link>
      <guid>https://forem.com/analogjs/bridging-analog-to-angular-with-esbuild-and-vite-472j</guid>
      <description>&lt;p&gt;It wasn't long ago that &lt;a href="https://dev.to/analogjs/announcing-analogjs-10-19an"&gt;Analog went 1.0&lt;/a&gt; bringing a stable full-stack meta-framework to the Angular community. One of the biggest conversations around Analog is the SFC and if its only available in Analog applications. There's good news, as this post covers how you can use Analog features in your existing Angular applications.&lt;/p&gt;

&lt;p&gt;TL;DR GitHub Repo - &lt;a href="https://github.com/brandonroberts/angular-esbuild-analog-example" rel="noopener noreferrer"&gt;https://github.com/brandonroberts/angular-esbuild-analog-example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you've been outside of the Angular bubble and wondered how we got here, Josh Morony has a video on what started as the &lt;code&gt;.ng&lt;/code&gt; file format for Angular, and how it evolved into the Analog SFC.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/15vHXCMhl6U"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Customizing Esbuild in Angular Applications
&lt;/h2&gt;

&lt;p&gt;Much has been said about Angular's migration from Webpack to esbuild and Vite, dramatically improving build performance and developer experience. We can take this a step further with a custom esbuild builder that allows additional features including esbuild plugins, middleware, and HTML transformers. &lt;/p&gt;

&lt;p&gt;The Angular Devkit exposes these APIs for library authors to build on top of what Angular handles out of the box. &lt;a href="https://twitter.com/jebbacca" rel="noopener noreferrer"&gt;Jenia "JeB" Barabanov&lt;/a&gt; has been maintaining custom Angular builders for Webpack and Jest for a while already, and introduced a custom builder for esbuild and the Vite dev server.&lt;/p&gt;

&lt;p&gt;You can check out his repo at: &lt;a href="https://github.com/just-jeb/angular-builders" rel="noopener noreferrer"&gt;https://github.com/just-jeb/angular-builders&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With this custom esbuild builder, it opens up the door to add a custom esbuild plugin to support the Analog SFC.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding the Analog SFC to an Angular application
&lt;/h2&gt;

&lt;p&gt;With the custom esbuild builder, you have the option to try the Analog SFC in an Angular 17.1+ application. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: The Analog SFC is still experimental!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With that out of the way, let's dive in!&lt;/p&gt;

&lt;p&gt;First, you need to install the custom esbuild builder and Analog Vite plugin for Angular:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i &lt;span class="nt"&gt;-D&lt;/span&gt; @angular-builders/custom-esbuild @analogjs/vite-plugin-angular
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, you need to update the &lt;code&gt;angular.json&lt;/code&gt; builder for &lt;code&gt;build&lt;/code&gt; to use the new builder.&lt;/p&gt;

&lt;p&gt;For the application builder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- "builder": "@angular-devkit/build-angular:application",
+ "builder": "@angular-builders/custom-esbuild:application",
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the dev-server builder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- "builder": "@angular-devkit/build-angular:dev-server",
+ "builder": "@angular-builders/custom-esbuild:dev-server",
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, create an &lt;code&gt;esbuild&lt;/code&gt; directory in the root of the application with two files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── esbuild
│   ├── plugins.js
│   ├── package.json
└── angular.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;package.json&lt;/code&gt;, add &lt;code&gt;{ "type": "module" }&lt;/code&gt; and save it.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;plugins.js&lt;/code&gt;, add the esbuild plugin for the Analog SFC.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;analogSFC&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@analogjs/vite-plugin-angular/esbuild&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;analogSFC&lt;/span&gt;&lt;span class="p"&gt;()];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;options&lt;/code&gt; for the application builder, add a &lt;code&gt;plugins&lt;/code&gt; array that includes the path to the &lt;code&gt;esbuild/plugins.js&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"builder"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@angular-builders/custom-esbuild:application"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"options"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"outputPath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dist/angular-esbuild-analog-example"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"plugins"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"./esbuild/plugins.js"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, create an &lt;code&gt;analog.d.ts&lt;/code&gt; in the &lt;code&gt;src&lt;/code&gt; directory with some type information.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ImportAttributes&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;analog&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;imports&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;providers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;viewProviders&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;exposes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;declare&lt;/span&gt; &lt;span class="nb"&gt;global&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Window&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/**
     * Define the metadata for the component.
     * @param metadata
     */&lt;/span&gt;
    &lt;span class="nl"&gt;defineMetadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Omit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;
        &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;template&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;standalone&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;changeDetection&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;styles&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;outputs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;inputs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="cm"&gt;/**
     * Invoke the callback when the component is initialized.
     */&lt;/span&gt;
    &lt;span class="nl"&gt;onInit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initFn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="cm"&gt;/**
     * Invoke the callback when the component is destroyed.
     */&lt;/span&gt;
    &lt;span class="nl"&gt;onDestroy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;destroyFn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;declare&lt;/span&gt; &lt;span class="kr"&gt;module&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;*.analog&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Type&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cmp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;cmp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now comes the fun part! &lt;/p&gt;

&lt;p&gt;Create a &lt;code&gt;hello.analog&lt;/code&gt; file in the &lt;code&gt;src&lt;/code&gt; folder with a component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="c1"&gt;// hello.analog&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;
    Hello Angular from Analog SFC
  &lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
    {{count()}}
  &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;(click)=&lt;/span&gt;&lt;span class="s"&gt;"add()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Increment&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lastly, in the &lt;code&gt;app.routes.ts&lt;/code&gt; file, define a route that navigates to the &lt;code&gt;Hello&lt;/code&gt; component. Analog SFCs can be used in combination with the Angular Router!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Routes&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/router&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Hello&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./hello.analog&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Routes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Hello&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run &lt;code&gt;ng serve&lt;/code&gt; and navigate to the application running locally.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft28wtmdmohqreq50jmpc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft28wtmdmohqreq50jmpc.png" alt="Analog SFC in Angular" width="800" height="501"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now ship to production! Just kidding 😉. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Analog SFCs are also interopable with Angular components, but must be enabled by the &lt;code&gt;experimental-local&lt;/code&gt; &lt;code&gt;compilationMode&lt;/code&gt; in the &lt;code&gt;tsconfig.json&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We've love for you to try out the SFC and give us your feedback. To find out more, check out the &lt;a href="https://analogjs.org/docs/experimental/sfc" rel="noopener noreferrer"&gt;Analog SFC&lt;/a&gt; docs. Also join the community on &lt;a href="https://chat.analogjs.org" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Using a custom esbuild builders opens up many possibilities to bring more Analog features to Angular applications. We're excited to explore more opportunities in the future. If you're also interested to learn more about how Analog and Vite work together with Angular, check out the &lt;a href="https://angularindepth.com/posts/1523/angular-analog-and-vite" rel="noopener noreferrer"&gt;Angular, Analog, and Vite&lt;/a&gt; post by Robin Goetz.&lt;/p&gt;

&lt;h2&gt;
  
  
  Join the Community 🥇
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Visit and Star the &lt;a href="https://github.com/analogjs/analog" rel="noopener noreferrer"&gt;GitHub Repo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Join the &lt;a href="https://chat.analogjs.org" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Follow us on &lt;a href="https://twitter.com/analogjs" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you enjoyed this post, click the ❤️ so other people will see it. Follow &lt;a href="https://twitter.com/analogjs" rel="noopener noreferrer"&gt;AnalogJS&lt;/a&gt; and &lt;a href="https://twitter.com/brandontroberts" rel="noopener noreferrer"&gt;me&lt;/a&gt; on Twitter/X, and subscribe to my &lt;a href="https://youtube.com/brandonrobertsdev?sub_confirmation=1" rel="noopener noreferrer"&gt;YouTube Channel&lt;/a&gt; for more content!&lt;/p&gt;

</description>
      <category>angular</category>
      <category>vite</category>
    </item>
    <item>
      <title>Announcing AnalogJS 1.0 🚀</title>
      <dc:creator>Brandon Roberts</dc:creator>
      <pubDate>Thu, 14 Mar 2024 19:10:34 +0000</pubDate>
      <link>https://forem.com/analogjs/announcing-analogjs-10-19an</link>
      <guid>https://forem.com/analogjs/announcing-analogjs-10-19an</guid>
      <description>&lt;p&gt;After many months of development and testing, we're excited to announce the 1.0 release of AnalogJS! The &lt;code&gt;1.0&lt;/code&gt; release includes many features that help developers ship websites and applications, faster, with Angular.&lt;/p&gt;

&lt;p&gt;This release marks the first major release of Analog, giving developers a more stable starting point to build with Analog. We will continue getting feedback from developers that helps us continue to improve and innovate on the project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Features ⭐️
&lt;/h2&gt;

&lt;p&gt;Analog is the meta-framework built on top of Angular, powered by &lt;a href="https://vitejs.dev" rel="noopener noreferrer"&gt;Vite&lt;/a&gt;, a next generation open-source build tool, and &lt;a href="https://nitro.unjs.io" rel="noopener noreferrer"&gt;Nitro&lt;/a&gt;, an open-source server engine framework. Here are some of its features, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First-class support for the Vite ecosystem (Vitest, Playwright, Cypress, and more)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://analogjs.org/docs/features/routing/overview" rel="noopener noreferrer"&gt;Filesystem-based routing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://analogjs.org/docs/features/routing/content" rel="noopener noreferrer"&gt;Support for markdown&lt;/a&gt; pages and blogs &lt;/li&gt;
&lt;li&gt;&lt;a href="https://analogjs.org/docs/features/api/overview" rel="noopener noreferrer"&gt;Support for API/server routes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Hybrid &lt;a href="https://analogjs.org/docs/features/server/server-side-rendering" rel="noopener noreferrer"&gt;SSR&lt;/a&gt;/&lt;a href="https://analogjs.org/docs/features/server/static-site-generation" rel="noopener noreferrer"&gt;SSG&lt;/a&gt; with sitemap and RSS feed support&lt;/li&gt;
&lt;li&gt;Supports Angular CLI/&lt;a href="https://analogjs.org/docs/integrations/nx" rel="noopener noreferrer"&gt;Nx workspaces&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Integration with &lt;a href="https://trpc.io" rel="noopener noreferrer"&gt;tRPC&lt;/a&gt; for type-safe server interactions&lt;/li&gt;
&lt;li&gt;Server and deployment support&lt;/li&gt;
&lt;li&gt;And more!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Contributions and Community 🤓
&lt;/h2&gt;

&lt;p&gt;AnalogJS would not be where it is without a team of core contributors and collaborators.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/goetzrobin" rel="noopener noreferrer"&gt;Robin Goetz&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/markostdev" rel="noopener noreferrer"&gt;Marko Stanimirović&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/LuisHCCDev" rel="noopener noreferrer"&gt;Luis Castro&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/nartc1410" rel="noopener noreferrer"&gt;Chau Tran&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/joshuamorony" rel="noopener noreferrer"&gt;Joshua Morony&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/villanuevand" rel="noopener noreferrer"&gt;Andrés Villanueva&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, thanks to the &lt;a href="https://github.com/analogjs/analog#contributors-" rel="noopener noreferrer"&gt;80+ contributors&lt;/a&gt; to the project, whether through code, documentation, tests, or even just trying out the project. &lt;/p&gt;

&lt;p&gt;The project already has surpassed 2000 stars on &lt;a href="https://github.com/analogjs/analog" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;, 500+ members on &lt;a href="https://chat.analogjs.org" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;, 1000+ followers on &lt;a href="https://twitter.com/analogjs" rel="noopener noreferrer"&gt;Twitter/X&lt;/a&gt;, and was accepted into the first &lt;a href="https://accelerator.github.com/" rel="noopener noreferrer"&gt;GitHub Accelerator Cohort&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/H4U6udLcM-Q"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;If you'd like to take Analog for a spin, check out this blog post on &lt;a href="https://dev.to/analogjs/how-to-build-a-blog-with-analog-and-angular-4pk2"&gt;Building a Blog&lt;/a&gt; with Analog and Angular. If you want to get involved in the project, check out the &lt;a href="https://github.com/analogjs/analog" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;We are continuing to make building fullstack websites and application with Analog and Angular as seamless as possible, and extending the Angular ecosystem through integrations with &lt;a href="https://astro.build" rel="noopener noreferrer"&gt;Astro&lt;/a&gt;, &lt;a href="https://nx.dev" rel="noopener noreferrer"&gt;Nx&lt;/a&gt;, &lt;a href="https://analogjs.org/docs/features/testing/vitest" rel="noopener noreferrer"&gt;Vitest&lt;/a&gt;, &lt;a href="https://storybook.js.org" rel="noopener noreferrer"&gt;Storybook&lt;/a&gt;, and more. &lt;/p&gt;

&lt;p&gt;We have also introduced a new Single File Component format in Analog for authoring components and directives. &lt;/p&gt;

&lt;p&gt;Below is an example of a &lt;code&gt;hello.analog&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Hello Analog&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;

  Count: {{ count() }}

  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;(click)=&lt;/span&gt;&lt;span class="s"&gt;"increment()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Increment
  &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What started as a &lt;code&gt;.ng&lt;/code&gt; file extension for components and directives using Angular has evolved into the Analog SFC, along with features including support for &lt;a href="https://github.com/analogjs/analog/discussions/901" rel="noopener noreferrer"&gt;auto-imports&lt;/a&gt;, inline markdown templates, page routes, and more. We are continuing to iterate on this approach, and exploring options to enable this format in Angular applications as the future of Analog progresses. &lt;/p&gt;

&lt;p&gt;We've already received very positive feedback, and even further development on supporting this format, including an &lt;a href="https://plugins.jetbrains.com/plugin/23913-analog?noRedirect=true" rel="noopener noreferrer"&gt;IDEA Plugin for the Analog SFC&lt;/a&gt; that's available in the EAP version of WebStorm. Thanks to &lt;a href="https://twitter.com/niklas_wortmann" rel="noopener noreferrer"&gt;Jan-Niklas Wortmann&lt;/a&gt; and &lt;a href="https://twitter.com/PiotrekTomiak" rel="noopener noreferrer"&gt;Piotr Tomiak&lt;/a&gt; from the JetBrains team for the initial development of the plugin. You can also contribute to the plugin on &lt;a href="https://github.com/analogjs/idea-plugin" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Partner with Analog 🤝
&lt;/h2&gt;

&lt;p&gt;We are looking for companies to partner with on the Analog project to support development of the project. Thanks to &lt;a href="https://snyder.tech/" rel="noopener noreferrer"&gt;Snyder Technologies&lt;/a&gt; for being an early adopter and promoter of Analog, &lt;a href="https://nx.dev" rel="noopener noreferrer"&gt;Nx&lt;/a&gt; for joining us as a sponsor, &lt;a href="https://houseofangular.io" rel="noopener noreferrer"&gt;House of Angular&lt;/a&gt;, and many other backers of the project.&lt;/p&gt;

&lt;p&gt;Find out more information on our &lt;a href="https://analogjs.org/docs/sponsoring" rel="noopener noreferrer"&gt;partnership opportunities&lt;/a&gt; or reach out directly to sponsor[at]analogjs.org. &lt;/p&gt;

&lt;h2&gt;
  
  
  Join the Community 🥇
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Visit and Star the &lt;a href="https://github.com/analogjs/analog" rel="noopener noreferrer"&gt;GitHub Repo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Join the &lt;a href="https://chat.analogjs.org" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Follow us on &lt;a href="https://twitter.com/analogjs" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you enjoyed this post, click the ❤️ so other people will see it. Follow &lt;a href="https://twitter.com/analogjs" rel="noopener noreferrer"&gt;AnalogJS&lt;/a&gt; and &lt;a href="https://twitter.com/brandontroberts" rel="noopener noreferrer"&gt;me&lt;/a&gt; on Twitter/X, and subscribe to my &lt;a href="https://youtube.com/brandonrobertsdev?sub_confirmation=1" rel="noopener noreferrer"&gt;YouTube Channel&lt;/a&gt; for more content!&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Announcing the 0.2.0 release of Analog 🎉</title>
      <dc:creator>Brandon Roberts</dc:creator>
      <pubDate>Mon, 21 Aug 2023 13:11:39 +0000</pubDate>
      <link>https://forem.com/analogjs/announcing-the-020-release-of-analog-aa1</link>
      <guid>https://forem.com/analogjs/announcing-the-020-release-of-analog-aa1</guid>
      <description>&lt;p&gt;After many months of development and testing, we're excited to announce the first stable release of Analog! The &lt;code&gt;0.2.0&lt;/code&gt; release includes many features that help developers ship applications and websites faster, with Angular.&lt;/p&gt;

&lt;p&gt;This release helps us move towards a &lt;code&gt;1.0&lt;/code&gt; release while giving developers an opportunity to use Analog. Feedback from developers helps us to continue improve and innovate on the project.&lt;/p&gt;

&lt;h1&gt;
  
  
  Features ⭐️
&lt;/h1&gt;

&lt;p&gt;Analog is the meta-framework built on top of Angular. Here are some of its features, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First-class support for the Vite ecosystem (Vitest, Playwright, Cypress, and more)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://analogjs.org/docs/features/routing/overview" rel="noopener noreferrer"&gt;Filesystem-based routing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://analogjs.org/docs/features/routing/content" rel="noopener noreferrer"&gt;Support for markdown&lt;/a&gt; pages and blogs &lt;/li&gt;
&lt;li&gt;&lt;a href="https://analogjs.org/docs/features/api/overview" rel="noopener noreferrer"&gt;Support for API/server routes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Hybrid &lt;a href="https://analogjs.org/docs/features/server/server-side-rendering" rel="noopener noreferrer"&gt;SSR&lt;/a&gt;/&lt;a href="https://analogjs.org/docs/features/server/static-site-generation" rel="noopener noreferrer"&gt;SSG&lt;/a&gt; with sitemap and RSS feed support&lt;/li&gt;
&lt;li&gt;Supports Angular CLI/&lt;a href="https://analogjs.org/docs/integrations/nx" rel="noopener noreferrer"&gt;Nx workspaces&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Integration with &lt;a href="https://trpc.io" rel="noopener noreferrer"&gt;tRPC&lt;/a&gt; for type-safe server interactions&lt;/li&gt;
&lt;li&gt;And more!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Community 🤓
&lt;/h2&gt;

&lt;p&gt;Thank to you all the &lt;a href="https://github.com/analogjs/analog#contributors-" rel="noopener noreferrer"&gt;contributors&lt;/a&gt; to the project, whether its been through code, documentation, tests, or even just trying out the project. &lt;/p&gt;

&lt;p&gt;The project already has close to 1500 stars on GitHub, 300+ members on Discord, 900+ followers on Twitter, and was accepted into the first &lt;a href="https://accelerator.github.com/" rel="noopener noreferrer"&gt;GitHub Accelerator Cohort&lt;/a&gt;. This only the beginning, as we look forward to continuing to improve the project and grow the community around it.&lt;/p&gt;

&lt;p&gt;If you'd like to take Analog for a spin, check out this blog post on &lt;a href="https://dev.to/analogjs/how-to-build-a-blog-with-analog-and-angular-4pk2"&gt;Building a Blog&lt;/a&gt; with Analog and Angular. If you want to get involved in the project, check out the &lt;a href="https://github.com/analogjs/analog" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Partner with Analog 🤝
&lt;/h2&gt;

&lt;p&gt;We are looking for companies to partner with on the Analog project to support development of the project. Thanks to &lt;a href="https://snyder.tech/" rel="noopener noreferrer"&gt;Snyder Technologies&lt;/a&gt; for being an early &lt;a href="https://twitter.com/benpsnyder/status/1671389794545328128?s=20" rel="noopener noreferrer"&gt;adopter and promoter&lt;/a&gt; of Analog.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1671389794545328128-606" src="https://platform.twitter.com/embed/Tweet.html?id=1671389794545328128"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1671389794545328128-606');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1671389794545328128&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;Find out more information on our &lt;a href="https://analogjs.org/docs/sponsoring" rel="noopener noreferrer"&gt;partnership opportunities&lt;/a&gt; or reach out directly to sponsor[at]analogjs.org. &lt;/p&gt;

&lt;h2&gt;
  
  
  Join the Community 🥇
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Visit and Star the &lt;a href="https://github.com/analogjs/analog" rel="noopener noreferrer"&gt;GitHub Repo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Join the &lt;a href="https://chat.analogjs.org" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Follow us on &lt;a href="https://twitter.com/analogjs" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you enjoyed this post, click the ❤️ so other people will see it. Follow &lt;a href="https://twitter.com/brandontroberts" rel="noopener noreferrer"&gt;me on Twitter&lt;/a&gt; and subscribe to my &lt;a href="https://youtube.com/brandonrobertsdev?sub_confirmation=1" rel="noopener noreferrer"&gt;YouTube Channel&lt;/a&gt; for more content!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>angular</category>
      <category>metaframework</category>
    </item>
    <item>
      <title>How to Build a Blog with Analog and Angular ✍️</title>
      <dc:creator>Brandon Roberts</dc:creator>
      <pubDate>Mon, 21 Aug 2023 13:10:00 +0000</pubDate>
      <link>https://forem.com/analogjs/how-to-build-a-blog-with-analog-and-angular-4pk2</link>
      <guid>https://forem.com/analogjs/how-to-build-a-blog-with-analog-and-angular-4pk2</guid>
      <description>&lt;p&gt;Putting your thoughts together in your personal blog is a great way to build a further understanding about a topic, and also helps others who come across it in the future. Building a blog is also one of the best ways you can learn a web development stack. Meta-frameworks of today make this process easier. This post shows you how to build a static blog with Angular using Analog.&lt;/p&gt;

&lt;p&gt;Analog is the meta-framework that helps you ship applications and websites faster with Angular.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/H4U6udLcM-Q"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started 🎽
&lt;/h2&gt;

&lt;p&gt;To create a new Analog project, you can use the &lt;code&gt;create-analog&lt;/code&gt; package with your package manager of choice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm create analog@latest my-analog-blog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Follow the prompts to choose Analog, the latest version of Angular, and Tailwind:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;✔ Select a template: › Analog
✔ Select a variant: › angular-v16
✔ Would you like to add Tailwind to your project? … no
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And go into the newly created folder&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;my-analog-blog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, install the dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To start the development server, use the start command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Navigate to &lt;a href="http://localhost:5173" rel="noopener noreferrer"&gt;http://localhost:5173&lt;/a&gt; to see the application running in your browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding Markdown Support 🔌
&lt;/h2&gt;

&lt;p&gt;Analog comes with support for using markdown as content out of the box. To add support for rendering markdown content, add the &lt;code&gt;provideContent(withMarkdownRenderer())&lt;/code&gt; from the &lt;code&gt;@analogjs/content&lt;/code&gt; package to the &lt;code&gt;providers&lt;/code&gt; in the &lt;code&gt;app.config.ts&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;provideHttpClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/common/http&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ApplicationConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;provideClientHydration&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/platform-browser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;provideFileRouter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@analogjs/router&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;provideContent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;withMarkdownRenderer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@analogjs/content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;appConfig&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ApplicationConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;provideFileRouter&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="nf"&gt;provideHttpClient&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="nf"&gt;provideClientHydration&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="nf"&gt;provideContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;withMarkdownRenderer&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows you to use markdown content directly as routes, and to render markdown content inside of Angular components.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating Content Routes with Markdown 🧠
&lt;/h2&gt;

&lt;p&gt;Some pages in your blog are purely content-focused, where you  only need to display content from a markdown file. Markdown files can be use directly as pages.&lt;/p&gt;

&lt;p&gt;Create a markdown file in the &lt;code&gt;src/app/pages&lt;/code&gt; directory named &lt;code&gt;about.md&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;About&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Me"&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

This page is about me
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Frontmatter is supported also for additional metadata, such as title, description, metatags, and more.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Navigate to &lt;code&gt;http://localhost:5173/about&lt;/code&gt; to see the about page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating and Displaying a Blog Post ✍️
&lt;/h2&gt;

&lt;p&gt;Markdown files can also be used in combination with route components to display content. To create a custom page for a blog post, Analog provides a built-in component.&lt;/p&gt;

&lt;p&gt;First, create a markdown file in &lt;code&gt;src/content/my-first-post.md&lt;/code&gt; for the post.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;My First Post&lt;/span&gt;
&lt;span class="na"&gt;slug&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my-first-post&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

Hello World
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, define an interface for the shape of the data returned from the frontmatter. For this example, the interface is placed in the &lt;code&gt;src/app/models/post.ts&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;BlogPost&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, create a page component for the blog. This page serves as the parent layout for the listing the blog posts and displaying an individual blog post.&lt;/p&gt;

&lt;p&gt;Create the page component file in &lt;code&gt;src/app/pages/blog.page.ts&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;RouterOutlet&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/router&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;standalone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;RouterOutlet&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;h1&amp;gt;My Blog&amp;lt;/h1&amp;gt;

    &amp;lt;router-outlet /&amp;gt;
  `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BlogPage&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, create the page component file for displaying a blog post. &lt;/p&gt;

&lt;p&gt;Define a page component in &lt;code&gt;src/app/pages/blog/[slug].page.ts&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;MarkdownComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;injectContent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@analogjs/content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AsyncPipe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NgIf&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/common&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BlogPost&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/app/models/post&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;standalone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;MarkdownComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NgIf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;AsyncPipe&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;div *ngIf="post$ | async as post"&amp;gt;
      &amp;lt;h2&amp;gt;{{ post.attributes.title }}&amp;lt;/h2&amp;gt;

      &amp;lt;analog-markdown [content]="post.content" /&amp;gt;
    &amp;lt;/div&amp;gt;
  `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BlogPostPage&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;post$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;injectContent&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;BlogPost&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, Analog reads the &lt;code&gt;slug&lt;/code&gt; route parameter to determine which content file to read from the &lt;code&gt;src/content&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;injectContent&lt;/code&gt; reads the content from the markdown file based on the &lt;code&gt;slug&lt;/code&gt; route parameter. The content and attributes are provided as an Observable that could be converted to a signal also. The &lt;code&gt;MarkdownComponent&lt;/code&gt; displays the rendered markdown content.&lt;/p&gt;

&lt;p&gt;This page creates the &lt;code&gt;/blog/:slug&lt;/code&gt; route for displaying blog posts. Save the changes and visit the &lt;code&gt;http://localhost:5173/blog/my-first-post&lt;/code&gt; to view the blog post.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Read more about &lt;a href="https://analogjs.org/docs/features/routing/overview" rel="noopener noreferrer"&gt;how routing works&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Listing Blog Posts 📜
&lt;/h2&gt;

&lt;p&gt;Next up, let's display the blog posts. For this page, an index page for at &lt;code&gt;http://localhost:5173/blog&lt;/code&gt; will display a list of the blog posts.&lt;/p&gt;

&lt;p&gt;Create a page component under &lt;code&gt;src/app/pages/blog/index.page.ts&lt;/code&gt; to define the &lt;code&gt;/blog&lt;/code&gt; route.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AsyncPipe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NgFor&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/common&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;injectContentFiles&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@analogjs/content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;RouterLink&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/router&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BlogPost&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/app/models/post&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;standalone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;NgFor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;RouterLink&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;AsyncPipe&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;h2&amp;gt;Posts&amp;lt;/h2&amp;gt;

    &amp;lt;ul&amp;gt;
      &amp;lt;li *ngFor="let post of posts"&amp;gt;
        &amp;lt;a [routerLink]="['/blog', post.slug]"&amp;gt;{{ post.attributes.title }}&amp;lt;/a&amp;gt;
      &amp;lt;/li&amp;gt;
    &amp;lt;/ul&amp;gt; 
  `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IndexPage&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;injectContentFiles&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;BlogPost&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;injectContentFiles()&lt;/code&gt; function provides a static list of all the markdown files inside the &lt;code&gt;src/content&lt;/code&gt; folder, with the frontmatter already parsed and available to use in the component. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;BlogPost&lt;/code&gt; interface is used to add type safety for using the post &lt;code&gt;attributes&lt;/code&gt; in the template.&lt;/p&gt;

&lt;p&gt;Visit the &lt;code&gt;http://localhost:5173/blog&lt;/code&gt; to display the blog posts and navigate to the blog post created earlier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Redirecting to Blog List 🔄
&lt;/h2&gt;

&lt;p&gt;A list of blog posts can now be displayed, as well as individual blog posts. A redirect can also be used to navigate from the home page &lt;code&gt;/&lt;/code&gt; to the &lt;code&gt;/blog&lt;/code&gt; page.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A page component is not necessary to define a redirect. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Replace the contents of the &lt;code&gt;src/app/pages/index.page.ts&lt;/code&gt; with the redirect:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;RouteMeta&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@analogjs/router&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;routeMeta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;RouteMeta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;redirectTo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/blog&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;pathMatch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;full&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;RouteMeta allows you to attach additional route metadata to a route. Here it's using a redirect, but other metadata such as guards, resolvers, page titles, and more can be added.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Read more about &lt;a href="https://analogjs.org/docs/features/routing/metadata" rel="noopener noreferrer"&gt;route metadata&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Pre-Rendering Static Pages 📃
&lt;/h2&gt;

&lt;p&gt;Lastly, for a blog, using Static Site Generation by pre-rendering the content allows for better SEO, and enables the site to be navigated without JavaScript turned on.&lt;/p&gt;

&lt;p&gt;To pre-render routes, in the &lt;code&gt;vite.config.ts&lt;/code&gt;, update the &lt;code&gt;analog()&lt;/code&gt; plugin with a config object that includes a &lt;code&gt;prerender&lt;/code&gt; property. Define the routes to be pre-rendered into static HTML files during build time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="nf"&gt;analog&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;prerender&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/blog&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/blog/my-first-post&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/about&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Routes can also be defined using an async function if you need to define them dynamically.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Support for generating &lt;a href="https://analogjs.org/docs/features/server/static-site-generation#sitemap-generation" rel="noopener noreferrer"&gt;sitemaps&lt;/a&gt; and &lt;a href="https://analogjs.org/docs/features/api/overview#defining-xml-content" rel="noopener noreferrer"&gt;an RSS feed&lt;/a&gt; is also included.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Deployment 🚀
&lt;/h2&gt;

&lt;p&gt;To build the blog for deployment, run the build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, the static assets are placed into the &lt;code&gt;dist/analog/public&lt;/code&gt; folder for deployment. You can deploy Analog sites/applications to many different providers with little to no configuration including Netlify, Vercel, Firebase, and more.&lt;/p&gt;

&lt;p&gt;Visit the &lt;a href="https://analogjs.org/docs/features/deployment/overview" rel="noopener noreferrer"&gt;deployment docs&lt;/a&gt; to learn more.&lt;/p&gt;

&lt;p&gt;And that's it! 🤩&lt;/p&gt;

&lt;p&gt;The GitHub repo for this example blog is at: &lt;a href="https://github.com/brandonroberts/my-analog-blog" rel="noopener noreferrer"&gt;https://github.com/brandonroberts/my-analog-blog&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now the really creative part begins where you bring your own styles and customizations to the blog to really make it unique. 😉&lt;/p&gt;

&lt;h2&gt;
  
  
  Example Projects
&lt;/h2&gt;

&lt;p&gt;If you're looking for some inspiration on building your own blog, check out some blogs built with Analog and Angular.&lt;/p&gt;

&lt;p&gt;Robin Goetz - &lt;a href="https://goetzrobin.github.io/" rel="noopener noreferrer"&gt;Blog&lt;/a&gt; &lt;a href="https://github.com/goetzrobin/goetzrobin.github.io" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;br&gt;
Matthieu Riegler aka. Jean Mèche - &lt;a href="https://riegler.fr" rel="noopener noreferrer"&gt;Blog&lt;/a&gt; &lt;a href="https://github.com/JeanMeche/riegler.fr" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;br&gt;
Luis Castro - &lt;a href="https://mrrobot.dev" rel="noopener noreferrer"&gt;Blog&lt;/a&gt; &lt;a href="https://github.com/luishcastroc/blog" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;br&gt;
Chris Perko - &lt;a href="https://perko.dev" rel="noopener noreferrer"&gt;Blog&lt;/a&gt; &lt;a href="https://github.com/BaronVonPerko/perko-dev" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;br&gt;
Preston Lamb - &lt;a href="https://www.prestonlamb.com/" rel="noopener noreferrer"&gt;Blog&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Partner with Analog 🤝
&lt;/h2&gt;

&lt;p&gt;We are looking for companies to partner with on the Analog project to support development of the project. Thanks to &lt;a href="https://snyder.tech/" rel="noopener noreferrer"&gt;Snyder Technologies&lt;/a&gt; for being an early &lt;a href="https://twitter.com/benpsnyder/status/1671389794545328128?s=20" rel="noopener noreferrer"&gt;adopter and promoter&lt;/a&gt; of Analog.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1671389794545328128-205" src="https://platform.twitter.com/embed/Tweet.html?id=1671389794545328128"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1671389794545328128-205');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1671389794545328128&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;Find out more information on our &lt;a href="https://analogjs.org/docs/sponsoring" rel="noopener noreferrer"&gt;partnership opportunities&lt;/a&gt; or reach out directly to sponsor[at]analogjs.org. &lt;/p&gt;

&lt;h2&gt;
  
  
  Join the Community 🥇
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Visit and Star the &lt;a href="https://github.com/analogjs/analog" rel="noopener noreferrer"&gt;GitHub Repo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Join the &lt;a href="https://chat.analogjs.org" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Follow us on &lt;a href="https://twitter.com/analogjs" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you enjoyed this post, click the ❤️ so other people will see it. Follow &lt;a href="https://twitter.com/brandontroberts" rel="noopener noreferrer"&gt;me on Twitter&lt;/a&gt; and subscribe to my &lt;a href="https://youtube.com/brandonrobertsdev?sub_confirmation=1" rel="noopener noreferrer"&gt;YouTube Channel&lt;/a&gt; for more content!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>angular</category>
      <category>metaframework</category>
    </item>
    <item>
      <title>Fullstack Angular with Analog 🚀</title>
      <dc:creator>Brandon Roberts</dc:creator>
      <pubDate>Wed, 28 Jun 2023 14:55:45 +0000</pubDate>
      <link>https://forem.com/analogjs/fullstack-angular-with-analog-2mnj</link>
      <guid>https://forem.com/analogjs/fullstack-angular-with-analog-2mnj</guid>
      <description>&lt;p&gt;With the current iteration of the web ecosystem, many frameworks are taking a server-first approach to building applications and websites. This is largely being done through meta-frameworks, such as Next.JS, SvelteKit, Nuxt, Qwik City, and more. These meta-frameworks have features such as filesystem-based routing, server-side rendering, static site generation, built-in API routes, and more integrated into the developer experience. &lt;/p&gt;

&lt;p&gt;Analog is the meta-framework that helps you ship applications and websites faster with Angular.&lt;/p&gt;

&lt;h3&gt;
  
  
  Features
&lt;/h3&gt;

&lt;p&gt;Analog is built on top of Angular with additional capabilities including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First-class support for the Vite ecosystem (Vitest, Playwright, Cypress, and more)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://analogjs.org/docs/features/routing/overview" rel="noopener noreferrer"&gt;File-based routing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://analogjs.org/docs/features/routing/content" rel="noopener noreferrer"&gt;Support for using markdown as content routes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://analogjs.org/docs/features/api/overview" rel="noopener noreferrer"&gt;Support for API/server routes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Hybrid &lt;a href="https://analogjs.org/docs/features/server/server-side-rendering" rel="noopener noreferrer"&gt;SSR&lt;/a&gt;/&lt;a href="https://analogjs.org/docs/features/server/static-site-generation" rel="noopener noreferrer"&gt;SSG support&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Supports Angular CLI/&lt;a href="https://analogjs.org/docs/integrations/nx" rel="noopener noreferrer"&gt;Nx workspaces&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;And more integrations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's Dive In!&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started 🤓
&lt;/h2&gt;

&lt;p&gt;To create a new Analog project, you can use the &lt;code&gt;create-analog&lt;/code&gt; package with your package manager of choice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm create analog@latest analog-app
&lt;span class="nb"&gt;cd &lt;/span&gt;analog-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also &lt;a href="https://analogjs.org/docs/integrations/nx" rel="noopener noreferrer"&gt;scaffold a new project with Nx&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Install the dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And serve the application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Navigate to &lt;a href="http://localhost:5173" rel="noopener noreferrer"&gt;http://localhost:5173&lt;/a&gt; to see the application running in your browser.&lt;/p&gt;

&lt;p&gt;To build for deployment, run the build command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Fileystem-based Routing 🤖
&lt;/h2&gt;

&lt;p&gt;Analog provides filesystem-based routing on top of the Angular Router. &lt;/p&gt;

&lt;p&gt;For example, to define a &lt;code&gt;/about&lt;/code&gt; route, create a file named &lt;code&gt;src/app/pages/about.page.ts&lt;/code&gt; in the Analog project.&lt;/p&gt;

&lt;p&gt;Next, add a standalone Angular component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-about&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;standalone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;h2&amp;gt;Hello Analog&amp;lt;/h2&amp;gt;

    Analog is a meta-framework on top of Angular.
  `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AboutPageComponent&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save the changes and there's your route without any additional configuration!&lt;/p&gt;

&lt;p&gt;Navigate to &lt;a href="http://localhost:5173/about" rel="noopener noreferrer"&gt;http://localhost:5173/about&lt;/a&gt; to see the about page.&lt;/p&gt;

&lt;p&gt;Analog also supports static routes, dynamic routes, nested routes, catch-all routes, &lt;a href="https://analogjs.org/docs/features/routing/overview" rel="noopener noreferrer"&gt;and more&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  API Routes 🧑‍🔧
&lt;/h2&gt;

&lt;p&gt;Analog supports defining API routes that can be used to serve data to the application.&lt;/p&gt;

&lt;p&gt;API routes are defined in the &lt;code&gt;src/server/routes&lt;/code&gt; folder. API routes are also filesystem-based, and are exposed under the default &lt;code&gt;/api&lt;/code&gt; prefix in development.&lt;/p&gt;

&lt;p&gt;For example, to define an API route to send a "Hello Word" message as JSON:&lt;/p&gt;

&lt;p&gt;Create a &lt;code&gt;src/server/routes/v1/hello.ts&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineEventHandler&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;h3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineEventHandler&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello World&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save the changes, and now you can access this API route at &lt;code&gt;/api/v1/hello&lt;/code&gt;. Query databases, connect to your CMS, and perform other actions on the server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Server-Side Rendering and Static Site Generation 📈
&lt;/h2&gt;

&lt;p&gt;Server-Side Rendering and Static Site Generation can enhance your Angular application in terms of SEO and performance. Analog supports server-side rendering and static site generation out of the box, and is enabled by default.&lt;/p&gt;

&lt;p&gt;To build for deployment, run the build command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To pre-render pages, configure them in the &lt;code&gt;vite.config.ts&lt;/code&gt; at the root of the project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vite&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;analog&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@analogjs/platform&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// https://vitejs.dev/config/&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineConfig&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;mode&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;analog&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;prerender&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/about&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/blog&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/blog/posts/2023-06-28-my-first-post&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These routes are pre-rendered to static HTML at build time and sent to the client before the Angular application is loaded, providing a better user experience. The Angular application is then loaded, providing a continued interactive user experience for the website or application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deployment 🚀
&lt;/h2&gt;

&lt;p&gt;You can also deploy Analog applications to many different providers with little to no configuration including Netlify, Vercel, Firebase, and more.&lt;/p&gt;

&lt;p&gt;Visit the &lt;a href="https://analogjs.org/docs/features/deployment/overview" rel="noopener noreferrer"&gt;deployment docs&lt;/a&gt; to learn more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sponsor Analog 💰
&lt;/h2&gt;

&lt;p&gt;Analog is an MIT-licensed open-source project, but the effort needed to maintain this project is supported through sponsorships and contributions. We are looking for sponsorships and partnerships to support future development of the project.&lt;/p&gt;

&lt;p&gt;Consider &lt;a href="https://analogjs.org/docs/sponsoring" rel="noopener noreferrer"&gt;sponsoring the Analog project&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you are a business using Angular to build a revenue-generating product, sponsoring Analog and its development also helps your interests in pushing Analog and Angular forward. If you are an individual who supports open-source projects, considering sponsoring and contributing to Analog.&lt;/p&gt;

&lt;h2&gt;
  
  
  Join the Community 🤝
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Visit and Star the &lt;a href="https://github.com/analogjs/analog" rel="noopener noreferrer"&gt;GitHub Repo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Join the &lt;a href="https://chat.analogjs.org" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Follow us on &lt;a href="https://twitter.com/analogjs" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you liked this, click the ❤️ so other people will see it. Follow &lt;a href="https://twitter.com/brandontroberts" rel="noopener noreferrer"&gt;me on Twitter&lt;/a&gt; and subscribe to my &lt;a href="https://youtube.com/brandonrobertsdev?sub_confirmation=1" rel="noopener noreferrer"&gt;YouTube Channel&lt;/a&gt; for content on &lt;a href="https://angular.io" rel="noopener noreferrer"&gt;Angular&lt;/a&gt;, &lt;a href="https://analogjs.org" rel="noopener noreferrer"&gt;Analog&lt;/a&gt;, &lt;a href="https://ngrx.io" rel="noopener noreferrer"&gt;NgRx&lt;/a&gt;, and more!&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
