diff --git a/WaiAppStatic/Storage/Embedded/TH.hs b/WaiAppStatic/Storage/Embedded/TH.hs
--- a/WaiAppStatic/Storage/Embedded/TH.hs
+++ b/WaiAppStatic/Storage/Embedded/TH.hs
@@ -18,6 +18,10 @@
 import WaiAppStatic.Storage.Filesystem (defaultWebAppSettings)
 import qualified Data.ByteString as B
 import qualified Data.ByteString.Lazy as BL
+#if !MIN_VERSION_template_haskell(2, 8, 0)
+import qualified Data.ByteString.Char8 as B8
+import qualified Data.ByteString.Lazy.Char8 as BL8
+#endif
 import qualified Data.HashMap.Strict as M
 import qualified Data.Text as T
 import qualified Data.Text.Encoding as T
@@ -71,15 +75,30 @@
 -- the IORef will always be holding (NoFinalizers, []).  Therefore
 -- unsafeDupablePerformIO is safe.
 bytestringE :: B.ByteString -> ExpQ
+#if MIN_VERSION_template_haskell(2, 8, 0)
 bytestringE b = [| unsafeDupablePerformIO (unsafePackAddressLen (I# $lenE) $ctE) |]
     where
         lenE = litE $ intPrimL $ toInteger $ B.length b
         ctE = litE $ stringPrimL $ B.unpack b
+#else
+bytestringE b =
+    [| B8.pack $s |]
+  where
+    s = litE $ stringL $ B8.unpack b
+#endif
+
 bytestringLazyE :: BL.ByteString -> ExpQ
+#if MIN_VERSION_template_haskell(2, 8, 0)
 bytestringLazyE b = [| unsafeDupablePerformIO (unsafePackAddressLen (I# $lenE) $ctE) |]
     where
         lenE = litE $ intPrimL $ toInteger $ BL.length b
         ctE = litE $ stringPrimL $ BL.unpack b
+#else
+bytestringLazyE b =
+    [| B8.pack $s |]
+  where
+    s = litE $ stringL $ BL8.unpack b
+#endif
 
 -- | A template haskell expression which creates either an EmbeddedEntry or ReloadEntry.
 mkEntry :: EmbeddableEntry -> ExpQ
diff --git a/test/EmbeddedTestEntries.hs b/test/EmbeddedTestEntries.hs
new file mode 100644
--- /dev/null
+++ b/test/EmbeddedTestEntries.hs
@@ -0,0 +1,45 @@
+{-# LANGUAGE TemplateHaskell, QuasiQuotes, OverloadedStrings #-}
+
+module EmbeddedTestEntries where
+
+import WaiAppStatic.Storage.Embedded
+import qualified Data.Text as T
+import qualified Data.Text.Lazy as TL
+import qualified Data.Text.Lazy.Encoding as TL
+import qualified Data.ByteString.Lazy as BL
+
+body :: Int -> Char -> BL.ByteString
+body i c = TL.encodeUtf8 $ TL.pack $ take i $ repeat c
+
+mkEntries :: IO [EmbeddableEntry]
+mkEntries = return
+    -- An entry that should be compressed
+  [ EmbeddableEntry "e1.txt" 
+                    "text/plain" 
+                    (Left ("Etag 1", body 1000 'A'))
+
+    -- An entry so short that the compressed text is longer
+  , EmbeddableEntry "e2.txt"
+                    "text/plain"
+                    (Left ("Etag 2", "ABC"))
+
+    -- An entry that is not compressed because of the mime
+  , EmbeddableEntry "somedir/e3.txt"
+                    "xxx"
+                    (Left ("Etag 3", body 1000 'A'))
+
+    -- A reloadable entry
+  , EmbeddableEntry "e4.css"
+                    "text/css"
+                    (Right [| return ("Etag 4" :: T.Text, body 2000 'Q') |])
+
+    -- An entry without etag
+  , EmbeddableEntry "e5.txt"
+                    "text/plain"
+                    (Left ("", body 1000 'Z'))
+
+    -- A reloadable entry without etag
+  , EmbeddableEntry "e6.txt"
+                    "text/plain"
+                    (Right [| return ("" :: T.Text, body 1000 'W') |] )
+  ]
diff --git a/test/WaiAppEmbeddedTest.hs b/test/WaiAppEmbeddedTest.hs
new file mode 100644
--- /dev/null
+++ b/test/WaiAppEmbeddedTest.hs
@@ -0,0 +1,78 @@
+{-# LANGUAGE TemplateHaskell, OverloadedStrings #-}
+module WaiAppEmbeddedTest (embSpec) where
+
+import Codec.Compression.GZip (compress)
+import EmbeddedTestEntries
+import Network.Wai
+import Network.Wai.Application.Static (staticApp)
+import Network.Wai.Test
+import Test.Hspec
+import WaiAppStatic.Storage.Embedded
+
+embApp :: Application
+embApp = staticApp $(mkSettings mkEntries)
+
+defRequest :: Request
+defRequest = defaultRequest
+
+embSpec :: Spec
+embSpec = do
+    let embed = flip runSession embApp
+    describe "embedded, compressed entry" $ do
+        it "served correctly" $ embed $ do
+            req <- request (setRawPathInfo defRequest "e1.txt")
+            assertStatus 200 req
+            assertHeader "Content-Type" "text/plain" req
+            assertHeader "Content-Encoding" "gzip" req
+            assertHeader "ETag" "Etag 1" req
+            assertNoHeader "Last-Modified req" req
+            assertBody (compress $ body 1000 'A') req
+
+        it "304 when valid if-none-match sent" $ embed $ do
+            req <- request (setRawPathInfo defRequest "e1.txt")
+                             { requestHeaders = [("If-None-Match", "Etag 1")] }
+            assertStatus 304 req
+
+    describe "embedded, uncompressed entry" $ do
+        it "too short" $ embed $ do
+            req <- request (setRawPathInfo defRequest "e2.txt")
+            assertStatus 200 req
+            assertHeader "Content-Type" "text/plain" req
+            assertNoHeader "Content-Encoding" req
+            assertHeader "ETag" "Etag 2" req
+            assertBody "ABC" req
+
+        it "wrong mime" $ embed $ do
+            req <- request (setRawPathInfo defRequest "somedir/e3.txt")
+            assertStatus 200 req
+            assertHeader "Content-Type" "xxx" req
+            assertNoHeader "Content-Encoding" req
+            assertHeader "ETag" "Etag 3" req
+            assertBody (body 1000 'A') req
+
+    describe "reloadable entry" $
+        it "served correctly" $ embed $ do
+            req <- request (setRawPathInfo defRequest "e4.css")
+            assertStatus 200 req
+            assertHeader "Content-Type" "text/css" req
+            assertNoHeader "Content-Encoding" req
+            assertHeader "ETag" "Etag 4" req
+            assertBody (body 2000 'Q') req
+
+    describe "entries without etags" $ do
+        it "embedded entry" $ embed $ do
+            req <- request (setRawPathInfo defRequest "e5.txt")
+            assertStatus 200 req
+            assertHeader "Content-Type" "text/plain" req
+            assertHeader "Content-Encoding" "gzip" req
+            assertNoHeader "ETag" req
+            assertBody (compress $ body 1000 'Z') req
+
+        it "reload entry" $ embed $ do
+            req <- request (setRawPathInfo defRequest "e6.txt")
+            assertStatus 200 req
+            assertHeader "Content-Type" "text/plain" req
+            assertNoHeader "Content-Encoding" req
+            assertNoHeader "ETag" req
+            assertBody (body 1000 'W') req
+
diff --git a/wai-app-static.cabal b/wai-app-static.cabal
--- a/wai-app-static.cabal
+++ b/wai-app-static.cabal
@@ -1,5 +1,5 @@
 name:            wai-app-static
-version:         1.3.2
+version:         1.3.2.1
 license:         MIT
 license-file:    LICENSE
 author:          Michael Snoyman <michael@snoyman.com>
@@ -14,7 +14,7 @@
 Extra-source-files:
   images/folder.png
   images/haskell.png
-  test/WaiAppStaticTest.hs
+  test/*.hs
   test/a/b
   tests.hs
 
@@ -48,7 +48,7 @@
                    , cereal                    >= 0.3.5
                    , mime-types                >= 0.1      && < 0.2
                    , unordered-containers      >= 0.2
-                   , template-haskell          >= 2.8
+                   , template-haskell          >= 2.7
                    , zlib                      >= 0.5
 
     exposed-modules: Network.Wai.Application.Static
