diff --git a/api/album_get.go b/api/album_get.go
index 063b8e0b4fc01d444a3967fde450e521bdf9c940..928b2b4377eeb0cf4d070cfb70cd21c047ea7f1b 100644
--- a/api/album_get.go
+++ b/api/album_get.go
@@ -19,6 +19,19 @@ func GetAlbum(env environment.FrontendEnvironment) http.Handler {
 			http.Error(writer, err.Error(), http.StatusInternalServerError)
 			return
 		}
+		album.Images, err = env.Repositories.AlbumImages.List(album.Id)
+		if err != nil {
+			http.Error(writer, err.Error(), http.StatusInternalServerError)
+			return
+		}
+		for i, image := range album.Images {
+			err = image.LoadUrl(env.Storage, env.Configuration.Storage)
+			if err != nil {
+				http.Error(writer, err.Error(), http.StatusInternalServerError)
+				return
+			}
+			album.Images[i] = image
+		}
 
 		util.ReturnJson(writer, album)
 	})
diff --git a/api/album_list.go b/api/album_list.go
index c29898b288e3d57f20605c2b72b7c9ff938d1243..74d0f4e46d7c12fb75402633774fa7dd63914a94 100644
--- a/api/album_list.go
+++ b/api/album_list.go
@@ -22,6 +22,22 @@ func ListAlbums(env environment.FrontendEnvironment) http.Handler {
 			http.Error(writer, err.Error(), http.StatusInternalServerError)
 			return
 		}
+		for i, album := range albums {
+			album.Images, err = env.Repositories.AlbumImages.List(album.Id)
+			if err != nil {
+				http.Error(writer, err.Error(), http.StatusInternalServerError)
+				return
+			}
+			for j, image := range album.Images {
+				err = image.LoadUrl(env.Storage, env.Configuration.Storage)
+				if err != nil {
+					http.Error(writer, err.Error(), http.StatusInternalServerError)
+					return
+				}
+				album.Images[j] = image
+			}
+			albums[i] = album
+		}
 
 		util.ReturnJson(writer, albums)
 	})
diff --git a/api/albumimage_get.go b/api/albumimage_get.go
deleted file mode 100644
index f85a592cff15718f4fa800e40ac28eff5035638e..0000000000000000000000000000000000000000
--- a/api/albumimage_get.go
+++ /dev/null
@@ -1,25 +0,0 @@
-package api
-
-import (
-	"database/sql"
-	"git.kuschku.de/justjanne/imghost-frontend/environment"
-	"git.kuschku.de/justjanne/imghost-frontend/util"
-	"github.com/gorilla/mux"
-	"net/http"
-)
-
-func GetAlbumImage(env environment.FrontendEnvironment) http.Handler {
-	return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
-		vars := mux.Vars(request)
-		albumImage, err := env.Repositories.AlbumImages.Get(vars["albumId"], vars["imageId"])
-		if err == sql.ErrNoRows {
-			http.NotFound(writer, request)
-			return
-		} else if err != nil {
-			http.Error(writer, err.Error(), http.StatusInternalServerError)
-			return
-		}
-
-		util.ReturnJson(writer, albumImage)
-	})
-}
diff --git a/api/albumimage_list.go b/api/albumimage_list.go
deleted file mode 100644
index 9782852bbcdcc71fcdcebe82bda5b1fb1a0f7860..0000000000000000000000000000000000000000
--- a/api/albumimage_list.go
+++ /dev/null
@@ -1,25 +0,0 @@
-package api
-
-import (
-	"database/sql"
-	"git.kuschku.de/justjanne/imghost-frontend/environment"
-	"git.kuschku.de/justjanne/imghost-frontend/util"
-	"github.com/gorilla/mux"
-	"net/http"
-)
-
-func ListAlbumImages(env environment.FrontendEnvironment) http.Handler {
-	return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
-		vars := mux.Vars(request)
-		albumImages, err := env.Repositories.AlbumImages.List(vars["albumId"])
-		if err == sql.ErrNoRows {
-			http.NotFound(writer, request)
-			return
-		} else if err != nil {
-			http.Error(writer, err.Error(), http.StatusInternalServerError)
-			return
-		}
-
-		util.ReturnJson(writer, albumImages)
-	})
-}
diff --git a/cmd/frontend/main.go b/cmd/frontend/main.go
index 2fc245d18135044b2227ce68886907ff7e1e653a..c050e6eb05a90d7338d41facc4e26b33a8c00267 100644
--- a/cmd/frontend/main.go
+++ b/cmd/frontend/main.go
@@ -65,12 +65,6 @@ func main() {
 		api.DeleteAlbum(env)).Methods(http.MethodDelete, http.MethodOptions)
 
 	// Album Image API
-	router.Handle(
-		"/api/v1/albums/{albumId}/images",
-		api.ListAlbumImages(env)).Methods(http.MethodGet, http.MethodOptions)
-	router.Handle(
-		"/api/v1/albums/{albumId}/images/{imageId}",
-		api.GetAlbumImage(env)).Methods(http.MethodGet, http.MethodOptions)
 	router.Handle(
 		"/api/v1/albums/{albumId}/images/{imageId}",
 		api.UpdateAlbumImage(env)).Methods(http.MethodPost, http.MethodOptions)
diff --git a/model/album.go b/model/album.go
index 75da1e6da418997525fd60c6f01e249cc90fac8d..ba560d17bd1af1b80976117d2f6de84b3b12f85c 100644
--- a/model/album.go
+++ b/model/album.go
@@ -6,12 +6,13 @@ import (
 )
 
 type Album struct {
-	Id          string    `json:"id" db:"id"`
-	Owner       string    `json:"owner" db:"owner"`
-	Title       string    `json:"title" db:"title"`
-	Description string    `json:"description" db:"description"`
-	CreatedAt   time.Time `json:"created_at" db:"created_at"`
-	UpdatedAt   time.Time `json:"updated_at" db:"updated_at"`
+	Id          string       `json:"id" db:"id"`
+	Owner       string       `json:"owner" db:"owner"`
+	Title       string       `json:"title" db:"title"`
+	Description string       `json:"description" db:"description"`
+	CreatedAt   time.Time    `json:"created_at" db:"created_at"`
+	UpdatedAt   time.Time    `json:"updated_at" db:"updated_at"`
+	Images      []AlbumImage `json:"images"`
 }
 
 func (album Album) VerifyOwner(user User) error {
diff --git a/model/album_image.go b/model/album_image.go
index b757f7fb6102e69fb73118247318900c3c0ae5f3..5d3b09fdb1ef42bd29969b958fcf1541f68b5f0b 100644
--- a/model/album_image.go
+++ b/model/album_image.go
@@ -1,8 +1,19 @@
 package model
 
+import (
+	"git.kuschku.de/justjanne/imghost-frontend/configuration"
+	"git.kuschku.de/justjanne/imghost-frontend/storage"
+)
+
 type AlbumImage struct {
 	Album       string `json:"album" db:"album"`
 	Image       string `json:"image" db:"image"`
 	Title       string `json:"title" db:"title"`
 	Description string `json:"description" db:"description"`
+	Url         string `json:"url"`
+}
+
+func (image *AlbumImage) LoadUrl(storage storage.Storage, config configuration.StorageConfiguration) (err error) {
+	image.Url = storage.UrlFor(config.ImageBucket, image.Image).String()
+	return
 }
diff --git a/ui/src/App.tsx b/ui/src/App.tsx
index 76da868bf1f2b06b55ff55835bbfd3709cb6043b..8fae9ddd27f5404dc92e8139c57d74b0e89f7481 100644
--- a/ui/src/App.tsx
+++ b/ui/src/App.tsx
@@ -1,6 +1,6 @@
 import React from 'react';
 import './App.css';
-import ImageList from "./ImageList";
+import ImageList from "./components/ImageList";
 import {BaseUrlProvider} from './api/baseUrlContext';
 import {QueryClient, QueryClientProvider} from "react-query";
 
diff --git a/ui/src/ImageList.tsx b/ui/src/ImageList.tsx
deleted file mode 100644
index ca223227be3e40e00bca9d8ee265873a20e8b3bc..0000000000000000000000000000000000000000
--- a/ui/src/ImageList.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import React from 'react';
-import './App.css';
-import {useListImages} from "./api/useListImages";
-
-export default function ImageList() {
-    const {status, data, error} = useListImages();
-    return (
-        <div>
-            <p>{status}</p>
-            <p>{error as string}</p>
-            <ul>
-                {data?.map(info => (
-                    <li key={info.id}>
-                        <p>{info.id}</p>
-                        <p>{info.owner}</p>
-                        <p>{info.title}</p>
-                        <p>{info.description}</p>
-                        <p>{info.original_name}</p>
-                        <p>{info.mime_type}</p>
-                        <p>{info.created_at}</p>
-                        <p>{info.updated_at}</p>
-                        <p>{info.state}</p>
-                        <p>{info.url}</p>
-                        <img src={info.url+"t"} alt=""/>
-                    </li>
-                ))}
-            </ul>
-        </div>
-    );
-}
diff --git a/ui/src/api/model/Album.ts b/ui/src/api/model/Album.ts
index a612891a4168d05ca3e42a13db68d1d72e5d06e9..fcd24df627cba6169e8f327881fd5105fcb08c75 100644
--- a/ui/src/api/model/Album.ts
+++ b/ui/src/api/model/Album.ts
@@ -1,3 +1,5 @@
+import {AlbumImage} from "./AlbumImage";
+
 export interface Album {
     id: string,
     owner: string,
@@ -5,4 +7,5 @@ export interface Album {
     description: string,
     created_at: string,
     updated_at: string,
+    images: AlbumImage[],
 }
diff --git a/ui/src/api/model/AlbumImage.ts b/ui/src/api/model/AlbumImage.ts
index 01e165a85a940356042174b43e695b7bf812303c..787d4d9061d0340d5a694e5c6a36feed2ebc26dc 100644
--- a/ui/src/api/model/AlbumImage.ts
+++ b/ui/src/api/model/AlbumImage.ts
@@ -3,4 +3,5 @@ export interface AlbumImage {
     image: string,
     title: string,
     description: string,
+    url: string,
 }
diff --git a/ui/src/api/useGetAlbum.ts b/ui/src/api/useGetAlbum.ts
new file mode 100644
index 0000000000000000000000000000000000000000..79c34a7bd3e383c612cf8945bcd0054a5bce3939
--- /dev/null
+++ b/ui/src/api/useGetAlbum.ts
@@ -0,0 +1,20 @@
+import {useQuery} from "react-query";
+import axios from "axios";
+import {useBaseUrl} from "./baseUrlContext";
+import {Album} from "./model/Album";
+
+export const useGetAlbum = (albumId: string) => {
+    const baseUrl = useBaseUrl();
+    return useQuery(
+        ["album", albumId],
+        () => axios.get<Album>(
+            `api/v1/albums/${albumId}`,
+            {
+                baseURL: baseUrl
+            }
+        ).then(it => it.data),
+        {
+            keepPreviousData: true
+        }
+    );
+}
diff --git a/ui/src/api/useGetImage.ts b/ui/src/api/useGetImage.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6f6fc1b7e460d420f598b5b1788fb9613e339bf0
--- /dev/null
+++ b/ui/src/api/useGetImage.ts
@@ -0,0 +1,20 @@
+import {useQuery} from "react-query";
+import axios from "axios";
+import {useBaseUrl} from "./baseUrlContext";
+import {Image} from "./model/Image";
+
+export const useGetImage = (imageId: string) => {
+    const baseUrl = useBaseUrl();
+    return useQuery(
+        ["image", imageId],
+        () => axios.get<Image>(
+            `api/v1/images/${imageId}`,
+            {
+                baseURL: baseUrl
+            }
+        ).then(it => it.data),
+        {
+            keepPreviousData: true
+        }
+    );
+}
diff --git a/ui/src/api/useListAlbums.ts b/ui/src/api/useListAlbums.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6f408304ba670d975deaa071d6a910f7371b27ae
--- /dev/null
+++ b/ui/src/api/useListAlbums.ts
@@ -0,0 +1,20 @@
+import {useQuery} from "react-query";
+import axios from "axios";
+import {useBaseUrl} from "./baseUrlContext";
+import {Album} from "./model/Album";
+
+export const useListAlbums = () => {
+    const baseUrl = useBaseUrl();
+    return useQuery(
+        "albums",
+        () => axios.get<Album[]>(
+            "api/v1/albums",
+            {
+                baseURL: baseUrl
+            }
+        ).then(it => it.data),
+        {
+            keepPreviousData: true
+        }
+    );
+}
diff --git a/ui/src/api/useListImages.ts b/ui/src/api/useListImages.ts
index d0e7ccf3bad6ba6c4a2ae92e822d5570976c7ebd..76d74e0315118c647ef39299ecea19becf31e732 100644
--- a/ui/src/api/useListImages.ts
+++ b/ui/src/api/useListImages.ts
@@ -6,7 +6,7 @@ import {Image} from "./model/Image";
 export const useListImages = () => {
     const baseUrl = useBaseUrl();
     return useQuery(
-        "connector-deployments",
+        "images",
         () => axios.get<Image[]>(
             "api/v1/images",
             {
diff --git a/ui/src/components/AlbumImageView.tsx b/ui/src/components/AlbumImageView.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..a2de68b405822583cc3bdd03c677a0897ce6e097
--- /dev/null
+++ b/ui/src/components/AlbumImageView.tsx
@@ -0,0 +1,17 @@
+import React from "react";
+import {AlbumImage} from "../api/model/AlbumImage";
+
+export interface AlbumImageProps {
+    image: AlbumImage
+}
+
+export default function AlbumImageView({image}: AlbumImageProps) {
+    return (
+        <div>
+            <p>{image.image}</p>
+            <p>{image.title}</p>
+            <p>{image.description}</p>
+            <img src={image.url + "t"} alt=""/>
+        </div>
+    )
+}
diff --git a/ui/src/components/AlbumList.tsx b/ui/src/components/AlbumList.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..6b827d3f76ad18d536698f4a08020937817027bd
--- /dev/null
+++ b/ui/src/components/AlbumList.tsx
@@ -0,0 +1,22 @@
+import React from 'react';
+import '../App.css';
+import {useListAlbums} from "../api/useListAlbums";
+import AlbumView from "./AlbumView";
+
+export default function AlbumList() {
+    const {status, data, error} = useListAlbums();
+    return (
+        <div>
+            <p>{status}</p>
+            <p>{error as string}</p>
+            <ul>
+                {data?.map(album => (
+                    <AlbumView
+                        key={album.id}
+                        album={album}
+                    />
+                ))}
+            </ul>
+        </div>
+    );
+}
diff --git a/ui/src/components/AlbumView.tsx b/ui/src/components/AlbumView.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..96546c1cb0e745800e2e698d19da7301571c57f4
--- /dev/null
+++ b/ui/src/components/AlbumView.tsx
@@ -0,0 +1,28 @@
+import AlbumImageView from "./AlbumImageView";
+import React from "react";
+import {Album} from "../api/model/Album";
+
+export interface AlbumProps {
+    album: Album
+}
+
+export default function AlbumView({album}: AlbumProps) {
+    return (
+        <div>
+            <p>{album.id}</p>
+            <p>{album.owner}</p>
+            <p>{album.title}</p>
+            <p>{album.description}</p>
+            <p>{album.created_at}</p>
+            <p>{album.updated_at}</p>
+            <ul>
+                {album.images.map(image => (
+                    <AlbumImageView
+                        key={image.image}
+                        image={image}
+                    />
+                ))}
+            </ul>
+        </div>
+    );
+}
diff --git a/ui/src/components/ImageList.tsx b/ui/src/components/ImageList.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..f7b025d801f7c6052268586c1a3eaded0ffdd4a1
--- /dev/null
+++ b/ui/src/components/ImageList.tsx
@@ -0,0 +1,22 @@
+import React from 'react';
+import '../App.css';
+import {useListImages} from "../api/useListImages";
+import ImageView from "./ImageView";
+
+export default function ImageList() {
+    const {status, data, error} = useListImages();
+    return (
+        <div>
+            <p>{status}</p>
+            <p>{error as string}</p>
+            <ul>
+                {data?.map(image => (
+                    <ImageView
+                        key={image.id}
+                        image={image}
+                    />
+                ))}
+            </ul>
+        </div>
+    );
+}
diff --git a/ui/src/components/ImageView.tsx b/ui/src/components/ImageView.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..83bb5c55e38243c509a559573d70297e76368181
--- /dev/null
+++ b/ui/src/components/ImageView.tsx
@@ -0,0 +1,23 @@
+import {Image} from "../api/model/Image";
+import React from "react";
+
+export interface ImageProps {
+    image: Image
+}
+
+export default function ImageView({image}: ImageProps) {
+    return (
+        <div>
+            <p>{image.id}</p>
+            <p>{image.owner}</p>
+            <p>{image.title}</p>
+            <p>{image.description}</p>
+            <p>{image.original_name}</p>
+            <p>{image.mime_type}</p>
+            <p>{image.created_at}</p>
+            <p>{image.updated_at}</p>
+            <p>{image.state}</p>
+            <img src={image.url + "t"} alt=""/>
+        </div>
+    )
+}