- Angular app using TailwindCSS components to display images from the Unsplash Images API
- Note: to open web links in a new window use: ctrl+click on link
- About and Contact pages give more information on app using Tailwind CSS cards
- To build for production Tailwind’s purge option is used to tree-shake unused styles and optimize final build size.
- RxJS take(1) operater used to take first element from the Unsplash & Github observable streams then close them, so unsubscribing is not necessary.
- The Github basic user info API does not require an API key. The Unsplash API does.
- Angular HttpClient GET request response overloads 1 to 15 carefully considered, especially http header 'observe' and 'responseType', to ensure correct response type from photo service which returns type
Observable<ArrayBuffer>
when the Home page functiononChangePhoto()
is expecting interface typeObservable<IUnsplashResponse>
Home | About | Contact |
- Angular framework v17
- Angular PWA v17 - app uses service workers so app will stay up if there is a loss of network - all necessary files are cached, including index.html, icons etc.
- Angular async pipes used with Unsplash asynchronous Observable objects
- Reactive Extensions Library for Javascript RxJS v7
- TailwindCSS v3 CSS framework
- http-server v14 command-line HTTP server to view the PWA
- Netlify CLI to deploy app on Netlify
- Run
npm i
to install dependencies. - Get yourself an Unsplash Login & API Key.
- Add API key to the
environments.ts
file - Run
ng serve
for a dev server. Navigate tohttp://localhost:4200/
. The app will automatically reload if you change any of the source files. - Run
npm run build
for a production build with CSS purging. - Run
npm run lint
to lint all files and fix where possible - The build artifacts will be stored in the
dist/angular-tailwind-unsplash
directory.
- No tests set up
photo.service.ts
- code to fetch Unsplash photo data and return it as an Observable
photoQuery(options: { query: string; orientation: string }): Observable<any> {
const queryParams = new HttpParams()
.set('query', options.query)
.set('orientation', options.orientation);
return this.http
.get(`${this.baseUrl}/photos/random`, {
...this.httpOptions,
params: queryParams,
})
.pipe(
take(1),
tap(data => console.log(data)),
catchError(err => {
return throwError(
() =>
`There was a problem fetching data from the Unsplash API: ${err.error.errors.toString()}`
);
})
);
}
- Lazy-loading of About and Contact pages
- All 3 pages have good Lighthouse test scores
- Tailwind build for production CSS purge results in a very small styles bundle (about 2.13kB)
- CodiumAI used to improve and document code
- Status: Working PWA. All files pass linting. Minor error with Unsplash samesite attributes to fix.
- To-Do: Add CSP. Add text compression (Brotli, GZip...). Deploy (env. variable add to Netlify), splash screens, tests, replace robots file info etc. and redo lighthouse.
- Angular Architects: article: Extending the Angular CLI’s build process without ejecting
- StackOverflow: How to solve semi-colon expected css(css-semicolonexpected)
- dev.to: Setup TailwindCSS in Angular the easy way
- Free svg site for butterfly svg on about page
- Stackoverflow: How to add rel=“preconnect” to tags other than link?
- Angular Architects: What’s new in Angular 17?
- This project is licensed under the terms of the MIT license.
- Repo created by ABateman, email:
[email protected]