# Components

Course: [Angular](https://www.devtutorials.ai/learn/angular) · Section: Angular Fundamentals
Source: https://www.devtutorials.ai/learn/angular/fundamentals/components

> What a component is, standalone components, creating one with the CLI, the @Component decorator and its metadata, selectors, templates and styles, and how to render, nest and reuse components.

## What Are Components?

A component is a reusable building block that defines one part of the user interface and the logic behind it.

An Angular app is a set of components, such as a header, a menu and a product card, placed inside one another.

Each component has three parts:

- **A class.** TypeScript code that stores the component's data and defines its methods, such as what happens when a button is clicked.
- **A template.** The HTML that defines what the component displays on the screen.
- **Styles.** The CSS that sets the component's colors, spacing and layout.

### Real-World Example

An e-commerce product page is typically split into components such as `Header`, `SearchBar`, `ProductGallery`, `PriceBox`, `ReviewList` and `CartButton`.

Each component has its own template, styles and logic, so a team can build and test `ReviewList` without touching `PriceBox`.

The same `ProductCard` component renders every item on the search results page, the wishlist and the "Recommended for you" section.

<figure className="ngc-fig">
<svg viewBox="0 0 640 262" role="img" aria-label="A component is built from the @Component decorator, a class, a template and styles.">
<defs><marker id="ngc-b1" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0 0L10 5L0 10z" className="ngc-arrowhead" /></marker></defs><g className="ngc-node ngc-solid c-red"><rect x="20" y="20" width="180" height="44" rx="9" /><text x="110.0" y="47" textAnchor="middle" style={{fontSize:"15px"}}>@Component</text></g><g className="ngc-node ngc-soft c-purple"><rect x="20" y="82" width="180" height="44" rx="9" /><text x="110.0" y="101" textAnchor="middle" style={{fontSize:"14px"}}>class</text><text className="ngc-sub" x="110.0" y="119" textAnchor="middle">data and logic</text></g><g className="ngc-node ngc-soft c-blue"><rect x="20" y="144" width="180" height="44" rx="9" /><text x="110.0" y="163" textAnchor="middle" style={{fontSize:"14px"}}>template</text><text className="ngc-sub" x="110.0" y="181" textAnchor="middle">the HTML</text></g><g className="ngc-node ngc-soft c-orange"><rect x="20" y="206" width="180" height="44" rx="9" /><text x="110.0" y="225" textAnchor="middle" style={{fontSize:"14px"}}>styles</text><text className="ngc-sub" x="110.0" y="243" textAnchor="middle">the CSS</text></g><line className="ngc-link ngc-flow c-slate" x1="202" y1="104" x2="398" y2="135" markerEnd="url(#ngc-b1)" /><line className="ngc-link ngc-flow c-slate" x1="202" y1="166" x2="398" y2="135" markerEnd="url(#ngc-b1)" /><line className="ngc-link ngc-flow c-slate" x1="202" y1="228" x2="398" y2="135" markerEnd="url(#ngc-b1)" /><line className="ngc-link ngc-flow c-slate" x1="202" y1="42" x2="398" y2="135" markerEnd="url(#ngc-b1)" /><g className="ngc-pulse"><g className="ngc-node ngc-solid c-green"><rect x="400" y="95" width="220" height="80" rx="9" /><text x="510.0" y="133" textAnchor="middle" style={{fontSize:"18px"}}>Component</text><text className="ngc-sub" x="510.0" y="151" textAnchor="middle">one piece of the screen</text></g></g>
</svg>
<figcaption>The decorator, the class, the template and the styles together make one component.</figcaption>
</figure>

Run the code below. It is one complete component with all three parts.

```angular runnable title="One component: class, template and styles"
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
    <h2>Welcome, {{ studentName }}!</h2>
    <p>You have {{ lessons }} lessons left.</p>
  `,
  styles: `
    h2 { color: #dd0031; }
    p { color: #555; }
  `,
})
export class App {
  studentName = 'Asha';
  lessons = 12;
}
```

Change `studentName` to your own name and run it again. The heading changes, because the template reads its value from the class.

## Standalone Components

A component often uses other components. For example, `App` uses `Header` and `Footer`. Angular must know which components `App` is allowed to use.

A **standalone component** lists those components itself, in its own `imports` list:

```ts
@Component({
  selector: 'app-root',
  imports: [Header, Footer],
  template: `<app-header /> <app-footer />`,
})
export class App {}
```

Older Angular apps did this differently. They used a separate file called a **module** (`NgModule`) to register components, and each component had to be added to that file before it could be used.

All new Angular components are standalone, so you do not need a module.

| Point | Old: module-based | New: standalone |
|---|---|---|
| Where a component is registered | Inside an `NgModule` file | No registration needed |
| How it uses other components | The module imports them | The component's own `imports` list |
| Extra files | One or more module files | None |
| Default in new projects | No | Yes |

In older code you may see `NgModule` files, or `standalone: true` written inside `@Component`. That setting turned a component into a standalone one. New Angular versions make every component standalone automatically, so you do not need to write it. Every example in this course uses standalone components.

## Creating Components

The easiest way to create a component is with the Angular CLI. Run this command inside your project folder:

```bash
ng generate component header
```

You can also use the short form:

```bash
ng g c header
```

The CLI creates a new folder with four files:

```text
src/app/header/
├── header.ts        the component class
├── header.html      the template
├── header.css       the styles
└── header.spec.ts   a test file
```

The class file looks like this:

```ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-header',
  imports: [],
  templateUrl: './header.html',
  styleUrl: './header.css',
})
export class Header {}
```

You can also write a component by hand. A component is a TypeScript class with the `@Component` decorator placed directly above it. In this course's practice editors, all the parts live in one file, so you can see everything at once.

```angular runnable title="A new Header component, used by App"
import { Component } from '@angular/core';

@Component({
  selector: 'app-header',
  template: `<header>📚 DevTutorials</header>`,
  styles: `header { padding: 8px 12px; background: #2563eb; color: white; border-radius: 6px; }`,
})
export class Header {}

@Component({
  selector: 'app-root',
  imports: [Header],
  template: `
    <app-header />
    <p>Start learning Angular today.</p>
  `,
})
export class App {}
```

## Component Decorator (`@Component`)

A **decorator** is a function, written with an `@` in front of its name, that adds information to the class below it. Angular reads this information to decide how to use the class.

`@Component` marks a class as a component. It also gives Angular the settings it needs to create the component: its tag name, its template and its styles.

```ts
@Component({
  selector: 'app-welcome',
  template: `<p>Hello!</p>`,
})
export class Welcome {}
```

Without `@Component`, the class is a plain TypeScript class. Angular cannot display it, because it has no template and no selector.

Put the decorator directly above the class, with nothing in between. Also import it first: `import { Component } from '@angular/core';`. If you forget the import, you get the error `Cannot find name 'Component'`.

## Component Metadata

The object inside `@Component({ ... })` is called **metadata**. Metadata is the configuration of the component: its tag name, its template, its styles and the other components it uses. Angular reads the metadata to create the component.

These are the metadata options you will use most:

| Option | What it does | Example |
|---|---|---|
| `selector` | The HTML tag name for the component | `'app-header'` |
| `template` | The HTML, written inside the class file | `` `<h1>Hi</h1>` `` |
| `templateUrl` | The path to a separate HTML file | `'./header.html'` |
| `styles` | The CSS, written inside the class file | `` `h1 { color: red; }` `` |
| `styleUrl` | The path to a separate CSS file | `'./header.css'` |
| `imports` | Other components this component uses | `[Header, Footer]` |

A component needs a template. Use either `template` or `templateUrl`, not both.

```angular runnable title="Every common metadata option in one component"
import { Component } from '@angular/core';

@Component({
  selector: 'app-badge',
  template: `<span>NEW</span>`,
  styles: `span { background: #15803d; color: white; padding: 2px 8px; border-radius: 10px; font-size: 12px; }`,
})
export class Badge {}

@Component({
  selector: 'app-root',
  imports: [Badge],
  template: `<h3>Angular Components <app-badge /></h3>`,
})
export class App {}
```

## Component Selector

The **selector** is the name of the component's HTML tag. When Angular finds this tag in another component's template, it creates the component at that position.

If the selector is `'app-badge'`, you write `<app-badge />` (or `<app-badge></app-badge>`) where you want the badge to appear.

<figure className="ngc-fig">
<svg viewBox="0 0 640 190" role="img" aria-label="The parent template contains the app-badge tag. On the screen, Angular replaces it with the Badge component.">
<defs><marker id="ngc-b2" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0 0L10 5L0 10z" className="ngc-arrowhead" /></marker></defs><text className="ngc-title c-purple" x="150" y="24" textAnchor="middle">Parent template</text><text className="ngc-title c-green" x="490" y="24" textAnchor="middle">On the screen</text><rect className="ngc-win" x="20" y="40" width="260" height="140" rx="10" /><text className="ngc-note" x="40" y="74" style={{fontFamily:"var(--mono)",fontSize:"14px"}}>&lt;h2&gt;My Store&lt;/h2&gt;</text><g className="ngc-pulse"><g className="ngc-node ngc-solid c-blue"><rect x="36" y="92" width="228" height="36" rx="9" /><text x="150.0" y="115" textAnchor="middle" style={{fontSize:"14px"}}>&lt;app-badge /&gt;</text></g></g><text className="ngc-note" x="40" y="160" style={{fontFamily:"var(--mono)",fontSize:"14px"}}>&lt;p&gt;Welcome&lt;/p&gt;</text><line className="ngc-link ngc-flow c-blue" x1="282" y1="110" x2="358" y2="110" markerEnd="url(#ngc-b2)" /><rect className="ngc-win" x="360" y="40" width="260" height="140" rx="10" /><text x="380" y="74" style={{fill:"var(--ink)",fontSize:"16px",fontWeight:700}}>My Store</text><g className="ngc-node ngc-solid c-green"><rect x="376" y="92" width="90" height="30" rx="9" /><text x="421.0" y="112" textAnchor="middle" style={{fontSize:"13px"}}>NEW</text></g><text x="380" y="160" style={{fill:"var(--ink)",fontSize:"14px"}}>Welcome</text>
</svg>
<figcaption>Write the selector as a tag. Angular shows the component in its place.</figcaption>
</figure>

Selector names follow a few rules:

- Use lower case letters.
- Use a dash, such as `app-header`. A dash keeps your tags apart from normal HTML tags like `header`.
- Start with a short prefix. New projects use `app`, so names look like `app-header` and `app-footer`.

## Component Template

The **template** is the HTML that defines the content and structure a component displays on the screen.

A template is standard HTML plus Angular template syntax. The most common feature is **interpolation**. You write a class property name inside double curly braces, like `{{ title }}`, and Angular replaces it with the property's current value.

```angular runnable title="The template shows values from the class"
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
    <h2>{{ course }}</h2>
    <p>Lessons: {{ lessons }}</p>
    <p>Hours: {{ lessons * 0.5 }}</p>
  `,
})
export class App {
  course = 'Angular Fundamentals';
  lessons = 14;
}
```

Interpolation can also contain a simple expression. `{{ lessons * 0.5 }}` multiplies the value of `lessons` by 0.5 and displays the result.

## Component Styles

**Component styles** are CSS rules that apply only to one component's template.

Angular limits these rules to the component that declares them. A style written for one component does not change the elements of any other component. This is called **style encapsulation**.

Run the example. Both components have a `<p>` tag. Only the `App` paragraph turns red.

```angular runnable title="Styles stay inside their own component"
import { Component } from '@angular/core';

@Component({
  selector: 'app-note',
  template: `<p>I am the Note component. My text stays normal.</p>`,
})
export class Note {}

@Component({
  selector: 'app-root',
  imports: [Note],
  template: `
    <p>I am the App component. My text is red.</p>
    <app-note />
  `,
  styles: `p { color: #dd0031; font-weight: bold; }`,
})
export class App {}
```

The rule `p { color: red }` lives in `App`. Angular applies it only to the paragraphs that `App` itself writes. The paragraph inside `Note` keeps its default color.

Component styles belong to the component. Use `src/styles.css` for styles that the whole app should share, such as fonts and page colors.

## Inline vs External Templates

You can store a template in one of two places.

An **inline template** is written inside the class file with `template`:

```ts
@Component({
  selector: 'app-header',
  template: `<h1>My Store</h1>`,
})
export class Header {}
```

An **external template** is written in its own `.html` file. The class points to it with `templateUrl`:

```ts
@Component({
  selector: 'app-header',
  templateUrl: './header.html',
})
export class Header {}
```

| Point | Inline (`template`) | External (`templateUrl`) |
|---|---|---|
| Where the HTML lives | Inside the `.ts` file | In a separate `.html` file |
| Best for | Short templates, a few lines | Longer templates |
| Editor help | Less HTML help | Full HTML highlighting and hints |
| Files to open | One | Two |
| What the CLI creates | No | Yes, by default |

A simple rule: if the HTML is longer than about three lines, move it to its own file.

The practice examples on this page keep each component in one file, so they use inline templates and inline styles. In a project created with the Angular CLI, each component keeps its template in an `.html` file and its styles in a `.css` file, and connects them with `templateUrl` and `styleUrl`.

## Inline vs External Styles

Styles can also be stored in one of two places.

**Inline styles** are written in the class file with `styles`:

```ts
@Component({
  selector: 'app-header',
  template: `<h1>My Store</h1>`,
  styles: `h1 { color: navy; }`,
})
export class Header {}
```

**External styles** are written in a `.css` file. The class points to it with `styleUrl`:

```ts
@Component({
  selector: 'app-header',
  templateUrl: './header.html',
  styleUrl: './header.css',
})
export class Header {}
```

| Point | Inline (`styles`) | External (`styleUrl`) |
|---|---|---|
| Where the CSS lives | Inside the `.ts` file | In a separate `.css` file |
| Best for | A few short rules | Many rules |
| Editor help | Less CSS help | Full CSS highlighting and hints |
| Stays inside the component | Yes | Yes |

Both forms keep the styles inside the component. The only difference is where you write them.

## Rendering Components

**Rendering** is the process in which Angular creates a component, builds the HTML from its template and inserts that HTML into the page.

Angular renders components in two situations:

1. **The root component** is started by `bootstrapApplication(App)` in `main.ts`. Angular puts it in the `<app-root>` tag of `index.html`.
2. **Every other component** is rendered when another template uses its selector.

To render a component inside another one, take two steps:

1. Add the component class to the parent's `imports` list.
2. Write its selector tag in the parent's template.

```angular runnable title="Render the same component three times"
import { Component } from '@angular/core';

@Component({
  selector: 'app-star',
  template: `<span>⭐</span>`,
})
export class Star {}

@Component({
  selector: 'app-root',
  imports: [Star],
  template: `
    <p>Rating: <app-star /><app-star /><app-star /></p>
  `,
})
export class App {}
```

Each `<app-star />` tag creates a new copy of the `Star` component. Add two more tags and run it again. You get a five-star rating.

## Nesting Components

**Nesting** means putting a component inside another component.

The outer component is the **parent**. The component inside it is the **child**. A child can have its own children, so the components form a tree.

<figure className="ngc-fig">
<svg viewBox="0 0 640 252" role="img" aria-label="App is the parent of Header and ProductList. ProductList is the parent of two ProductCard components.">
<line className="ngc-link" x1="320" y1="64" x2="170" y2="112" /><line className="ngc-link" x1="320" y1="64" x2="470" y2="112" /><line className="ngc-link" x1="470" y1="156" x2="390" y2="198" /><line className="ngc-link" x1="470" y1="156" x2="550" y2="198" /><g className="ngc-node ngc-solid c-red ngc-pop ngc-p1"><rect x="260" y="20" width="120" height="44" rx="9" /><text x="320.0" y="48" textAnchor="middle" style={{fontSize:"16px"}}>App</text></g><g className="ngc-node ngc-soft c-blue ngc-pop ngc-p2"><rect x="100" y="112" width="140" height="44" rx="9" /><text x="170.0" y="139" textAnchor="middle" style={{fontSize:"15px"}}>Header</text></g><g className="ngc-node ngc-soft c-blue ngc-pop ngc-p2"><rect x="400" y="112" width="140" height="44" rx="9" /><text x="470.0" y="139" textAnchor="middle" style={{fontSize:"15px"}}>ProductList</text></g><g className="ngc-node ngc-soft c-purple ngc-pop ngc-p3"><rect x="320" y="198" width="140" height="44" rx="9" /><text x="390.0" y="225" textAnchor="middle" style={{fontSize:"15px"}}>ProductCard</text></g><g className="ngc-node ngc-soft c-purple ngc-pop ngc-p3"><rect x="480" y="198" width="140" height="44" rx="9" /><text x="550.0" y="225" textAnchor="middle" style={{fontSize:"15px"}}>ProductCard</text></g><text className="ngc-note" x="170" y="190" textAnchor="middle">parent: App</text><text className="ngc-note" x="170" y="210" textAnchor="middle">children: Header, ProductList</text>
</svg>
<figcaption>A parent shows its children. Children can have their own children.</figcaption>
</figure>

```angular runnable title="Components inside components"
import { Component } from '@angular/core';

@Component({
  selector: 'app-product-card',
  template: `<li>🎧 Headphones · ₹1,999</li>`,
})
export class ProductCard {}

@Component({
  selector: 'app-product-list',
  imports: [ProductCard],
  template: `
    <h3>Products</h3>
    <ul><app-product-card /><app-product-card /></ul>
  `,
})
export class ProductList {}

@Component({
  selector: 'app-root',
  imports: [ProductList],
  template: `
    <h2>My Store</h2>
    <app-product-list />
  `,
})
export class App {}
```

Follow the tree from the top:

1. `App` displays a heading and the `ProductList` component.
2. `ProductList` displays its own heading and two `ProductCard` components.
3. Each parent imports only its own children. `App` does not import `ProductCard`.

## Reusable Components

A **reusable component** is a component you write once and use many times, each time with different data.

The parent passes data to the child through an **input**. An input is a class property that receives its value from the parent component. You mark a property as an input with `@Input()`. The parent then sets it in square brackets: `[title]="..."`.

<figure className="ngc-fig">
<svg viewBox="0 0 640 200" role="img" aria-label="One CourseCard component is used three times, showing Angular, TypeScript and RxJS.">
<defs><marker id="ngc-b3" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0 0L10 5L0 10z" className="ngc-arrowhead" /></marker></defs><g className="ngc-node ngc-solid c-red"><rect x="230" y="16" width="180" height="48" rx="9" /><text x="320.0" y="38" textAnchor="middle" style={{fontSize:"16px"}}>CourseCard</text><text className="ngc-sub" x="320.0" y="56" textAnchor="middle">written once</text></g><line className="ngc-link ngc-flow c-blue" x1="320" y1="66" x2="115" y2="128" markerEnd="url(#ngc-b3)" /><g className="ngc-node ngc-soft c-blue ngc-pop ngc-p1"><rect x="30" y="130" width="170" height="58" rx="9" /><text x="115.0" y="157" textAnchor="middle" style={{fontSize:"16px"}}>Angular</text><text className="ngc-sub" x="115.0" y="175" textAnchor="middle">20 hours</text></g><line className="ngc-link ngc-flow c-purple" x1="320" y1="66" x2="320" y2="128" markerEnd="url(#ngc-b3)" /><g className="ngc-node ngc-soft c-purple ngc-pop ngc-p2"><rect x="235" y="130" width="170" height="58" rx="9" /><text x="320.0" y="157" textAnchor="middle" style={{fontSize:"16px"}}>TypeScript</text><text className="ngc-sub" x="320.0" y="175" textAnchor="middle">12 hours</text></g><line className="ngc-link ngc-flow c-green" x1="320" y1="66" x2="525" y2="128" markerEnd="url(#ngc-b3)" /><g className="ngc-node ngc-soft c-green ngc-pop ngc-p3"><rect x="440" y="130" width="170" height="58" rx="9" /><text x="525.0" y="157" textAnchor="middle" style={{fontSize:"16px"}}>RxJS</text><text className="ngc-sub" x="525.0" y="175" textAnchor="middle">8 hours</text></g>
</svg>
<figcaption>One component, written once, shows different data each time.</figcaption>
</figure>

```angular runnable title="One card component, three different courses"
import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-course-card',
  template: `
    <div class="card">
      <strong>{{ title }}</strong>
      <span>{{ hours }} hours</span>
    </div>
  `,
  styles: `
    .card { display: flex; justify-content: space-between; padding: 8px 12px;
            margin: 6px 0; border: 1px solid #c7d2fe; border-radius: 8px; background: #eef2ff; }
  `,
})
export class CourseCard {
  @Input() title = '';
  @Input() hours = 0;
}

@Component({
  selector: 'app-root',
  imports: [CourseCard],
  template: `
    <app-course-card [title]="'Angular'" [hours]="20" />
    <app-course-card [title]="'TypeScript'" [hours]="12" />
    <app-course-card [title]="'RxJS'" [hours]="8" />
  `,
})
export class App {}
```

The `CourseCard` code is written once. The three cards share the same template and styles, but each card displays the title and hours passed to it.

Reusable components remove duplicated code. When you fix a bug or change the design in `CourseCard`, every card in the app receives the change.

## Component Naming Conventions

Consistent names make a project easier to read and maintain. Angular projects follow the same naming rules, so any Angular developer can locate a component's files quickly.

| Item | Rule | Example |
|---|---|---|
| Class name | PascalCase: every word starts with a capital letter | `ProductCard` |
| Selector | Prefix, a dash, then lower-case words joined by dashes | `app-product-card` |
| Folder | Lower-case words joined by dashes | `product-card/` |
| Class file | Same as the folder | `product-card.ts` |
| Template file | Same name, `.html` | `product-card.html` |
| Style file | Same name, `.css` | `product-card.css` |

When you run `ng g c product-card`, the CLI follows all of these rules for you.

New Angular projects use short class names such as `ProductCard`. Older projects add the word "Component", such as `ProductCardComponent`, and name the file `product-card.component.ts`. Both work. Pick one style and use it in the whole project.

## Common Mistakes

<div className="ngc-mistakes">

| Mistake | What you see | Fix |
|---|---|---|
| Child not added to `imports` | `NG0304: ... is not a known element` | Add the child class to the parent's `imports` list |
| `Component` not imported | `Cannot find name 'Component'` | Add `import { Component } from '@angular/core';` |
| Selector without a dash | Clashes with normal HTML tags | Use a prefix, such as `app-header` |
| Using the class name as a tag | `<ProductCard>` displays nothing | Use the selector: `<app-product-card />` |
| Both `template` and `templateUrl` | A build error about the template | Use only one of them |
| Expecting component styles to reach a child | The child does not change | Style the child in its own component |
| Wrong path in `templateUrl` | `Could not find template file` | Check the file name, starting with `./` |

</div>

## Check Yourself

## Exercises

## What to Remember

- A component defines one part of the user interface. It combines a class (data and logic), a template (HTML) and styles (CSS).
- `@Component` metadata tells Angular the selector, the template, the styles and the imports.
- To display a child component, add its class to the parent's `imports` list and write its selector tag in the parent's template. Use `@Input()` to pass data into a reusable component.

Next: **Angular Templates**, how a template connects HTML to the data and methods in the class.
