# Building a weather application

Aurelia 2 provides a powerful and flexible framework for building modern web applications. By integrating **Tailwind CSS** and **Vite**, we can create a fully responsive and beautifully styled **weather dashboard** that fetches real-time weather data. This guide will walk you through setting up the project, configuring Tailwind CSS, and building the UI.

***

## Prerequisites

Ensure you have [**Node.js**](https://nodejs.org/) (latest LTS version recommended) installed.

***

## 1. Setting Up the Aurelia Project with Vite

### Create a New Aurelia Project

Run the following command to scaffold a new Aurelia 2 project using **Vite**:

```bash
npx makes aurelia
```

Select **"Default TypeScript App"** and **"Vite"** as the bundler when prompted. When you're asked for a name, make something up or use `weather-app`.

### Navigate to Your Project Directory

```bash
cd weather-app
```

***

## 2. Installing and Configuring Tailwind CSS

### Install Tailwind CSS and Its Vite Plugin

To integrate **Tailwind CSS** with **Vite**, install the required dependencies:

```bash
npm install tailwindcss @tailwindcss/vite -D
```

### Configure Vite to Use Tailwind CSS

Update your **`vite.config.ts`** to include the Tailwind CSS Vite plugin:

```typescript
// vite.config.ts
import { defineConfig } from 'vite';
import aurelia from '@aurelia/vite-plugin';
import tailwindcss from '@tailwindcss/vite';

export default defineConfig({
  plugins: [aurelia(), tailwindcss()],
});
```

### Include Tailwind in Your CSS

In your scaffolded project, you'll see a `my-app.css` file. Open it and add the following:

```css
/* src/my-app.css */
@import 'tailwindcss';
```

Aurelia will automatically include this file when you run `npm start` because of the default conventions support in Aurelia projects.

***

## 3. Implementing the Weather Dashboard

### Fetching Weather Data

Sign up for a **free API key** from [**OpenWeatherMap**](https://openweathermap.org/api) to fetch real-time weather data. You get a few thousand requests per day for free.

Create a **Weather Service** to handle API requests:

```typescript
// src/services/weather-service.ts
import { resolve } from '@aurelia/kernel';
import { IHttpClient } from '@aurelia/fetch-client';

export class WeatherService {
  private http = resolve(IHttpClient);
  private apiKey = 'YOUR_API_KEY';
  private baseUrl = 'https://api.openweathermap.org/data/2.5/';

  async getWeatherByCity(city: string): Promise<any> {
    const response = await this.http.fetch(
      `${this.baseUrl}weather?q=${city}&appid=${this.apiKey}&units=metric`
    );
    if (response.ok) {
      return response.json();
    } else {
      throw new Error('City not found');
    }
  }
}
```

***

## 4. Creating the Weather Dashboard Component

### Weather Dashboard View Model

Create a **component** that fetches weather data and manages state:

```typescript
// src/components/weather-dashboard.ts
import { ICustomElementViewModel } from '@aurelia/runtime-html';
import { resolve } from '@aurelia/kernel';
import { WeatherService } from '../services/weather-service';

export class WeatherDashboard implements ICustomElementViewModel {
  private weatherService = resolve(WeatherService);
  public city = 'Brisbane';
  public weatherData: any = null;
  public errorMessage: string | null = null;

  async attached() {
    await this.fetchWeather();
  }

  async fetchWeather() {
    try {
      this.errorMessage = null;
      this.weatherData = await this.weatherService.getWeatherByCity(this.city);
    } catch (error) {
      this.errorMessage = error.message;
      this.weatherData = null;
    }
  }

  async search() {
    await this.fetchWeather();
  }
}
```

***

### Weather Dashboard View (HTML)

Now, style the **dashboard UI** with **Tailwind CSS**:

```html
<!-- src/components/weather-dashboard.html -->
<div class="max-w-md mx-auto p-6 bg-white shadow-xl rounded-lg">
  <h1 class="text-3xl font-bold mb-6 text-center text-blue-600">Weather Dashboard</h1>

  <form submit.trigger="search" class="flex mb-6">
    <input
      type="text"
      value.bind="city"
      placeholder="Enter city name"
      class="flex-grow p-2 border border-gray-300 rounded-l focus:ring focus:ring-blue-200"
    />
    <button
      type="submit"
      class="p-2 bg-blue-500 text-white rounded-r hover:bg-blue-600 transition"
    >
      Search
    </button>
  </form>

  <div if.bind="errorMessage" class="text-red-500 text-center font-semibold">
    <p>${errorMessage}</p>
  </div>

  <div if.bind="weatherData" class="text-center">
    <h2 class="text-xl font-semibold text-gray-900">${weatherData.name}, ${weatherData.sys.country}</h2>
    <p class="text-gray-700 text-lg">🌡️ ${weatherData.main.temp}°C</p>
    <p class="text-gray-600 capitalize">☁️ ${weatherData.weather[0].description}</p>
    <p class="text-gray-600">💧 Humidity: ${weatherData.main.humidity}%</p>
    <p class="text-gray-600">💨 Wind Speed: ${weatherData.wind.speed} m/s</p>
  </div>
</div>
```

***

## 5. Adding the Component to the Application

Include the **Weather Dashboard** component in your **main app**:

```html
<!-- src/my-app.html -->
<weather-dashboard></weather-dashboard>
```

***

## 6. Running the Application

Start the development server:

```bash
npm start
```

The browser will open automatically to the Aurelia app.

***

## 7. Additional Enhancements

* **Dark Mode Support**: Configure Tailwind to support dark mode and apply corresponding styles.
* **Responsive Design**: Utilize Tailwind’s responsive utilities for mobile-friendly UI.
* **Custom Themes**: Extend Tailwind’s theme in tailwind.config.js for custom branding.
* **Hourly Forecast**: Fetch and display hourly or weekly weather forecasts.

***

## Conclusion

This guide demonstrated how to **integrate Tailwind CSS with Aurelia 2 using Vite**, enabling a responsive, modern, and styled weather dashboard. With **real-time weather data** from OpenWeatherMap, this project highlights Aurelia’s data-binding and service integration capabilities.

For more details on **Tailwind CSS**, refer to the [official documentation](https://tailwindcss.com/docs).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.aurelia.io/tutorials/building-a-weather-application.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
