diff --git a/src/App.jsx b/src/App.jsx
index 225ee33807383ca265ee4d90afe80d939d6afbad..6a9b2098105e34447e3b8f41da573a1c9852ddea 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -3,6 +3,7 @@ import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
 import { KeycloakProvider } from "@react-keycloak/web";
 import * as Sentry from "@sentry/react";
 
+import { loadConfig } from "actions/global-info";
 import { initializeWSChannel } from "actions/ws";
 import Footer from "components/Footer";
 import Navbar from "components/Navbar";
@@ -75,6 +76,7 @@ const LoadingComponent = (
 
 const BaseApp = () => {
   initializeWSChannel.read();
+  loadConfig.read();
 
   return (
     <Router>
diff --git a/src/actions/global-info.js b/src/actions/global-info.js
new file mode 100644
index 0000000000000000000000000000000000000000..6e8c268fe43fd701446c53e45dc8d7ae69506586
--- /dev/null
+++ b/src/actions/global-info.js
@@ -0,0 +1,35 @@
+import isArray from "lodash/isArray";
+import { createAsyncAction, errorResult, successResult } from "pullstate";
+
+import { fetch } from "api";
+import { GlobalInfoStore } from "stores";
+
+export const loadConfig = createAsyncAction(
+  async () => {
+    try {
+      const resp = await fetch("/config");
+      const payload = await resp.json();
+
+      if (!isArray(payload)) {
+        return errorResult([], "Unexpected response format");
+      }
+
+      return successResult(payload);
+    } catch (err) {
+      return errorResult([], err.toString());
+    }
+  },
+  {
+    postActionHook: ({ result }) => {
+      if (!result.error) {
+        GlobalInfoStore.update((state) => {
+          result.payload.forEach((rawConfigItem) => {
+            if (rawConfigItem.id === "stream_url") {
+              state.streamUrl = rawConfigItem.value;
+            }
+          });
+        });
+      }
+    },
+  }
+);
diff --git a/src/pages/Home.css b/src/pages/Home.css
new file mode 100644
index 0000000000000000000000000000000000000000..d8210b5879d6f84c1ff834d223d9523238a5902d
--- /dev/null
+++ b/src/pages/Home.css
@@ -0,0 +1,14 @@
+/* auto-size iframe according to aspect ratio while keeping the 100% height */
+.iframe-container {
+  position: relative;
+  padding-bottom: 56.25%; /* 16:9 */
+  height: 0;
+}
+
+.iframe-container iframe {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+}
diff --git a/src/pages/Home.jsx b/src/pages/Home.jsx
index aaa2ec1246f6bc8882a93525358ea8212018db6f..4d3dc7e525853d034f3e79bf9a4debe6e257710f 100644
--- a/src/pages/Home.jsx
+++ b/src/pages/Home.jsx
@@ -17,7 +17,9 @@ import AnnouncementsContainer from "containers/AnnoucementsContainer";
 import PostFilters from "containers/PostFilters";
 import PostsContainer from "containers/PostsContainer";
 import { useActionConfirm } from "hooks";
-import { AuthStore, ProgramStore } from "stores";
+import { AuthStore, GlobalInfoStore, ProgramStore } from "stores";
+
+import "./Home.css";
 
 const NotYetStarted = ({ startAt }) => (
   <article className="container container--wide py-8 md:py-16 lg:py-32">
@@ -94,6 +96,7 @@ const Home = () => {
     scheduleIds,
   } = ProgramStore.useState();
   const { isAuthenticated, user } = AuthStore.useState();
+  const { streamUrl } = GlobalInfoStore.useState();
   const programEntry = currentId ? programEntries[currentId] : null;
   const [showProgramEditModal, setShowProgramEditModal] = useState(false);
   const [
@@ -191,15 +194,25 @@ const Home = () => {
             )}
           </div>
 
-          <iframe
-            width="100%"
-            height="500"
-            src="https://www.youtube.com/embed/73jJLspL8o8"
-            frameBorder="0"
-            allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
-            allowFullScreen=""
-            title="Video stream"
-          ></iframe>
+          {streamUrl && (
+            <div className="iframe-container">
+              <iframe
+                width="560"
+                height="315"
+                src={streamUrl}
+                frameBorder="0"
+                allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
+                allowFullScreen=""
+                title="Video stream"
+              />
+            </div>
+          )}
+          {!streamUrl && (
+            <p>
+              Server neposlal informaci o aktuálním streamu. Vyčkejte na
+              aktualizaci.
+            </p>
+          )}
         </section>
 
         <section className="cf2021__notifications">
diff --git a/src/stores.js b/src/stores.js
index f4e1511b998a6e84afec4917c1608a2f1e30ad06..c7db0904befc1db704ab16065c90966069734d95 100644
--- a/src/stores.js
+++ b/src/stores.js
@@ -1,6 +1,14 @@
 import memoize from "lodash/memoize";
 import { Store } from "pullstate";
 
+/** @type {CF2021.GlobalInfoStorePayload} */
+const globalInfoStoreInitial = {
+  onlineUsers: 0,
+  streamUrl: null,
+};
+
+export const GlobalInfoStore = new Store(globalInfoStoreInitial);
+
 /** @type {CF2021.AuthStorePayload} */
 const authStoreInitial = {
   isAuthenticated: false,
diff --git a/typings/cf2021.d.ts b/typings/cf2021.d.ts
index fbed0e076d90270ed75dfc7abd2134f954a2252f..33bb981157b5b9f7df0b58814fcfbc76d6028104 100644
--- a/typings/cf2021.d.ts
+++ b/typings/cf2021.d.ts
@@ -1,4 +1,9 @@
 declare namespace CF2021 {
+  export interface GlobalInfoStorePayload {
+    onlineUsers: number;
+    streamUrl?: string;
+  }
+
   interface ProgramScheduleEntry {
     id: number;
     number: string;