Static Site Generation (SSG)

Static Site Generation (SSG)

SSG (Static Site Generation) using Angular

?

What is static site Generation (SSG)?

In Static Site Generation the page HTML is rendered/generated at the build time. It means in production, the page HTML is generated when you run the build.

Steps to Create static page generation in Angular

To build a static website with Angular you can use Angular Universal and the built-in pre-render engine for the static site generation. Let's create an example that demonstrates Static Site Generation (SSG) using Angular. This involves pre-rendering pages at build time and serving them as static HTML files. We'll use Angular Universal's prerendering feature to achieve this.

Here's the step-by-step implementation:

Step-by-Step Implementation

1. Set Up a New Angular Project

First, create a new Angular project and add Angular Universal:

bash

ng new ssgExample --routing
cd ssgExample
ng add @nguniversal/express-engine        

2. Create the Standalone Components

Generate standalone components for Home, About, Contact, and Dashboard.

bash

ng generate component home --standalone
ng generate component about --standalone
ng generate component contact --standalone
ng generate component dashboard --standalone        


3. Implement the Components

Home Component

src/app/home/home.component.ts

typescript

import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';


@Component({

  selector: 'app-home',

  standalone: true,

  imports: [CommonModule, RouterModule],

  templateUrl: './home.component.html',

  styleUrls: ['./home.component.css']

})

export class HomeComponent {}        


src/app/home/home.component.html

html

<h2>Home</h2>
<p>Welcome to the home page. This page is pre-rendered.</p>        

About Component

src/app/about/about.component.ts

typescript

import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';

 

@Component({

  selector: 'app-about',

  standalone: true,

  imports: [CommonModule, RouterModule],

  templateUrl: './about.component.html',

  styleUrls: ['./about.component.css']

})

export class AboutComponent {}        


src/app/about/about.component.html

html

<h2>About</h2>
<p>This is the about page. This page is pre-rendered.</p>        

Contact Component (with Reactive Forms)

src/app/contact/contact.component.ts

typescript

import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ReactiveFormsModule, FormBuilder, FormGroup, Validators } from '@angular/forms';

 

@Component({

  selector: 'app-contact',

  standalone: true,

  imports: [CommonModule, ReactiveFormsModule],

  templateUrl: './contact.component.html',

  styleUrls: ['./contact.component.css']

})

export class ContactComponent {

  contactForm: FormGroup;

 

  constructor(private fb: FormBuilder) {

    this.contactForm = this.fb.group({

      name: ['', [Validators.required, Validators.minLength(3)]],

      email: ['', [Validators.required, Validators.email]],

      message: ['', [Validators.required, Validators.minLength(10)]]

    });

  }

 

  onSubmit(): void {

    if (this.contactForm.valid) {

      console.log('Form Submitted', this.contactForm.value);

    }

  }

}        


src/app/contact/contact.component.html

html

<h2>Contact</h2>
<form [formGroup]="contactForm" (ngSubmit)="onSubmit()">

  <div>

    <label for="name">Name</label>

    <input id="name" formControlName="name" />

    <div *ngIf="contactForm.get('name').invalid && contactForm.get('name').touched">

      Name is required and must be at least 3 characters long.

    </div>

  </div>

  <div>

    <label for="email">Email</label>

    <input id="email" formControlName="email" />

    <div *ngIf="contactForm.get('email').invalid && contactForm.get('email').touched">

      Valid email is required.

    </div>

  </div>

  <div>

    <label for="message">Message</label>

    <textarea id="message" formControlName="message"></textarea>

    <div *ngIf="contactForm.get('message').invalid && contactForm.get('message').touched">

      Message is required and must be at least 10 characters long.

    </div>

  </div>

  <button type="submit" [disabled]="contactForm.invalid">Submit</button>

</form>        


Dashboard Component

src/app/dashboard/dashboard.component.ts

typescript

import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';

@Component({

  selector: 'app-dashboard',

  standalone: true,

  imports: [CommonModule],

  templateUrl: './dashboard.component.html',

  styleUrls: ['./dashboard.component.css']

})

export class DashboardComponent {}        


src/app/dashboard/dashboard.component.html

html

<h2>Dashboard</h2>
<p>This is the dashboard page. This page is client-side rendered.</p>        

4. Update Routing for Lazy Loading

Update the routing module to use lazy loading for the standalone components.

src/app/app-routing.module.ts

typescript

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
 
const routes: Routes = [

  { path: '', loadComponent: () => import('./home/home.component').then(m => m.HomeComponent) },

  { path: 'about', loadComponent: () => import('./about/about.component').then(m => m.AboutComponent) },

  { path: 'contact', loadComponent: () => import('./contact/contact.component').then(m => m.ContactComponent) },

  { path: 'dashboard', loadComponent: () => import('./dashboard/dashboard.component').then(m => m.DashboardComponent) },

];

 

@NgModule({

  imports: [RouterModule.forRoot(routes)],

  exports: [RouterModule]

})

export class AppRoutingModule { }        


src/app/app.component.html

html

<nav>
<a routerLink="/">Home</a>

  <a routerLink="/about">About</a>

  <a routerLink="/contact">Contact</a>

  <a routerLink="/dashboard">Dashboard</a>

</nav>

<router-outlet></router-outlet>        

?

5. Update the App Module

Ensure the app module is set up correctly to support the standalone components and routing.

src/app/app.module.ts

typescript

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';


@NgModule({

  declarations: [

    AppComponent

  ],

  imports: [

    BrowserModule.withServerTransition({ appId: 'serverApp' }),

    AppRoutingModule

  ],

  providers: [],

  bootstrap: [AppComponent]

})

export class AppModule { }        


6. Configure Static Site Generation (SSG)

Update the angular.json file to include SSG configuration.

angular.json

json

?

{
 ...

  "projects": {

    "ssgExample": {

      ...

      "architect": {

        "build": {

          ...

        },

        "server": {

          ...

        },

        "prerender": {

          "builder": "@nguniversal/builders:prerender",

          "options": {

            "browserTarget": "ssgExample:build:production",

            "serverTarget": "ssgExample:server:production",

            "routes": [

              "/",

              "/about",

              "/contact"

            ]

          }

        }

      }

    }

  }

}        

?

7. Build and Prerender the Application

Build the application for static site generation (SSG):

bash

ng run ssgExample:prerender        

Running the Application

After prerendering, you can serve the static files using any static file server. For local testing, you can use a simple HTTP server like http-server.

First, install http-server globally if you don't have it:

bash

npm install -g http-server        

Then, serve the pre-rendered static files:

bash

http-server dist/ssgExample/browser        

Navigate to https://localhost:8080 in your browser. You should see:

  • The Home, About, and Contact pages rendered as static HTML.
  • The Dashboard page rendered client-side.

Summary

In this guide, we configured an Angular application for Static Site Generation (SSG) using Angular Universal. The example included:

  1. Creating a new Angular Project.
  2. Installing Angular Universal
  3. Reactive Forms: Implemented in the Contact component.
  4. Lazy Loading: Used for loading standalone components.
  5. Standalone Components: Created and configured for Home, About, Contact, and Dashboard.
  6. Configuring SSG(Static Site Generation) in angular.json for About and Contact pages.
  7. Running the application.


By configuring the Angular Universal's prerendering feature, we pre-render specific routes at build time and serve them as static HTML files, providing a fast and SEO-friendly experience.

?

要查看或添加评论,请登录

Gopalkrishna Hegde的更多文章

  • FOUNDATION MODELS AND LLM COMPARISON

    FOUNDATION MODELS AND LLM COMPARISON

    GEN AI MODELS Foundation models and Large Language Models are used in the context of Generative AI(Gen AI). Although…

    2 条评论
  • Angular Universal SSR(Server-Side Rendering)

    Angular Universal SSR(Server-Side Rendering)

    Angular Universal SSR (Server-Side Rendering) What is Angular Universal? Angular Universal is a pre-rendering solution…

  • Demystifying Common Git Errors

    Demystifying Common Git Errors

    Introduction: In the world of software development, Git has become the cornerstone of version control. It empowers…

  • Angular Architecture

    Angular Architecture

    Architecture Angular is a popular open-source framework for building web and mobile applications. It follows the…

  • SetValue v/s PatchValue

    SetValue v/s PatchValue

    We will learn about how set the model values in Reactive Forms. It is done using SetValue and PatchValue provided by…

  • Features of ASP.NET CORE

    Features of ASP.NET CORE

    Following are some of the features of ASP.NET CORE It is open source.

社区洞察

其他会员也浏览了