diff --git a/src/Yesod/Csp.hs b/src/Yesod/Csp.hs
--- a/src/Yesod/Csp.hs
+++ b/src/Yesod/Csp.hs
@@ -5,6 +5,7 @@
 module Yesod.Csp (
   cspPolicy
   , getCspPolicy
+  , cspMiddleware
   , EscapedURI
   , escapeAndParseURI
   , escapedTextForNonce
@@ -17,13 +18,17 @@
   , textSource
   ) where
 
+import qualified Data.CaseInsensitive as CI
 import           Data.Data          (Data)
 import           Data.List.NonEmpty
 import           Data.Text
 import qualified Data.Text          as T
+import qualified Data.Text.Encoding as TE
 import           Data.Typeable      (Typeable)
 import           Network.URI
 import           Yesod.Core
+import           Network.Wai        (Middleware, mapResponseHeaders,
+                                     modifyResponse)
 
 -- | Adds a "Content-Security-Policy" header to your response.
 --
@@ -36,11 +41,28 @@
 -- >     [whamlet|hello|]
 --
 cspPolicy :: (MonadHandler m) => DirectiveList -> m ()
-cspPolicy = addHeader "Content-Security-Policy" . directiveListToHeader
+cspPolicy = addHeader cspHeaderName . directiveListToHeader
 
+cspHeaderName :: Text
+cspHeaderName = "Content-Security-Policy"
+
 -- | Returns a generated Content-Security-Policy header.
 getCspPolicy :: DirectiveList -> Text
 getCspPolicy = directiveListToHeader
+
+-- | Creates a WAI 'Middleware' to add a Content-Security-Policy
+-- header to every response.
+cspMiddleware :: DirectiveList -> Middleware
+cspMiddleware = addHeaderMiddleware . mkHeader . directiveListToHeader
+  where
+    addHeaderMiddleware = modifyResponse . mapResponseHeaders . insertAt 5
+    mkHeader dltext = (cspHeaderNameBS, TE.encodeUtf8 dltext)
+    cspHeaderNameBS = CI.mk $ TE.encodeUtf8 cspHeaderName
+
+insertAt :: Int -> a -> [a] -> [a]
+insertAt n x xs =
+  let (h, t) = Prelude.splitAt n xs
+  in h ++ x : t
 
 newtype EscapedURI = EscapedURI { uri :: URI } deriving (Eq, Data, Typeable)
 
diff --git a/test/Test.hs b/test/Test.hs
--- a/test/Test.hs
+++ b/test/Test.hs
@@ -5,6 +5,7 @@
 {-# LANGUAGE TypeFamilies          #-}
 
 import           Data.Attoparsec.Text
+import           Data.Functor         ((<$>))
 import           Data.List.NonEmpty
 import           Data.Maybe
 import           Test.Hspec
@@ -14,7 +15,10 @@
 import           Yesod.Test
 
 data Test = Test
-mkYesod "Test" [parseRoutes| / HomeR GET |]
+mkYesod "Test" [parseRoutes|
+/ HomeR GET
+/nocsp NoCspR GET
+|]
 
 instance Yesod Test
 
@@ -23,8 +27,15 @@
   cspPolicy [ScriptSrc (Self :| []), StyleSrc (Https :| [Self])]
   defaultLayout [whamlet|hello|]
 
+getNoCspR :: Handler Html
+getNoCspR = do
+  defaultLayout [whamlet|hello|]
+
 main :: IO ()
-main = hspec $ yesodSpec Test $ do
+main = hspec $ tests >> middlewareTest
+
+tests :: Spec
+tests = yesodSpec Test $ do
   ydescribe "Generation" $ do
     yit "works" $ do
       let header = getCspPolicy [ScriptSrc (Self :| []), StyleSrc (Https :| [Self])]
@@ -88,3 +99,13 @@
       assertEq "with th" [csp|img-src 'self' https:;  script-src https://foo.com|] result
       let url = fromJust $ escapeAndParseURI "https://foo.com"
       assertEq "with antiquoting" [csp|img-src 'self' https:; script-src $url|] result
+
+middlewareTest :: Spec
+middlewareTest = yesodSpecApp Test getApp $ do
+  ydescribe "Middleware" $ do
+    yit "works" $ do
+      get NoCspR
+      assertHeader "Content-Security-Policy" "frame-ancestors 'self'"
+  where
+    getApp = cspMiddleware [FrameAncestors (Self :| [])] <$>
+             toWaiAppPlain Test
diff --git a/yesod-csp.cabal b/yesod-csp.cabal
--- a/yesod-csp.cabal
+++ b/yesod-csp.cabal
@@ -2,7 +2,7 @@
 -- documentation, see http://haskell.org/cabal/users-guide/
 
 name:                yesod-csp
-version:             0.2.2.0
+version:             0.2.3.0
 synopsis:            Add CSP headers to Yesod apps
 description:         Add CSP headers to Yesod apps. This helps reduce exposure to XSS attacks and bad assets.
 license:             MIT
@@ -32,6 +32,8 @@
                        , attoparsec
                        , template-haskell
                        , syb
+                       , wai
+                       , case-insensitive
   hs-source-dirs:      src
   default-language:    Haskell2010
   ghc-options:         -Wall
