diff --git a/include/components/config.hpp b/include/components/config.hpp
index fdda44c1..93e3fa62 100644
--- a/include/components/config.hpp
+++ b/include/components/config.hpp
@@ -338,6 +338,7 @@ class config {
       fallback = var.substr(pos + 1);
       var.erase(pos);
     }
+    var = file_util::expand(var);
 
     if (file_util::exists(var)) {
       m_log.info("File reference \"%s\" found", var);
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6db61117..04a8a490 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -73,7 +73,8 @@ if(BUILD_IPC_MSG)
     SOURCES
       ipc.cpp
       utils/env.cpp
-      utils/file.cpp)
+      utils/file.cpp
+      utils/string.cpp)
   target_compile_options(polybar-msg PUBLIC $<$<CXX_COMPILER_ID:GNU>:$<$<CONFIG:MinSizeRel>:-flto>>)
 endif()
 
diff --git a/src/utils/file.cpp b/src/utils/file.cpp
index d73c0fff..ddaa466f 100644
--- a/src/utils/file.cpp
+++ b/src/utils/file.cpp
@@ -9,6 +9,7 @@
 #include "errors.hpp"
 #include "utils/env.hpp"
 #include "utils/file.hpp"
+#include "utils/string.hpp"
 
 POLYBAR_NS
 
@@ -236,11 +237,22 @@ namespace file_util {
    * Path expansion
    */
   const string expand(const string& path) {
-    string p{path};
-    if (p[0] == '~') {
-      p.replace(0, 1, env_util::get("HOME"));
+    string ret;
+    vector<string> p_exploded = string_util::split(path, '/');
+    for (auto& section : p_exploded) {
+      switch(section[0]) {
+        case '$':
+          section = env_util::get(section.substr(1));
+          break;
+        case '~':
+          section = env_util::get("HOME");
+          break;
+      }
     }
-    return p;
+    ret = string_util::join(p_exploded, "/");
+    if (ret[0] != '/')
+      ret.insert(0, 1, '/');
+    return ret;
   }
 }