diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,9 @@
 # ChangeLog for shakespeare
 
+### 2.1.0
+
+* Add `OverloadedRecordDot`-style record access in expressions
+
 ### 2.0.30
 
 * Add `Text.Cassius.Ordered` and `Text.Lucius.Ordered` modules with parsers to maintain order between attributes and mixin blocks.
diff --git a/Text/Shakespeare/Base.hs b/Text/Shakespeare/Base.hs
--- a/Text/Shakespeare/Base.hs
+++ b/Text/Shakespeare/Base.hs
@@ -55,6 +55,11 @@
            | DerefBranch Deref Deref
            | DerefList [Deref]
            | DerefTuple [Deref]
+           | DerefGetField Deref String
+           -- ^ Record field access via @OverloadedRecordDot@. 'derefToExp' only supports this
+           -- feature on compilers which support @OverloadedRecordDot@.
+           --
+           -- @since 2.1.0
     deriving (Show, Eq, Read, Data, Typeable, Ord, Lift)
 
 derefParens, derefCurlyBrackets :: UserParser a Deref
@@ -105,7 +110,15 @@
         ys <- many1 $ try $ delim >> derefSingle
         skipMany $ oneOf " \t"
         return $ DerefBranch (DerefBranch op' $ foldl1 DerefBranch $ x : xs) (foldl1 DerefBranch ys)
-    derefSingle = derefTuple <|> derefList <|> derefOp <|> derefParens <|> numeric <|> strLit <|> ident
+    derefSingle = do
+        x <- derefTuple <|> derefList <|> derefOp <|> derefParens <|> numeric <|> strLit <|> ident
+        fields <- many recordDot
+        pure $ foldl DerefGetField x fields
+    recordDot = do
+        _ <- char '.'
+        x <- lower <|> char '_'
+        xs <- many (alphaNum <|> char '_' <|> char '\'')
+        pure (x : xs)
     deref' lhs =
         dollar <|> derefSingle'
                <|> return (foldl1 DerefBranch $ lhs [])
@@ -177,6 +190,12 @@
                                map Just $
 #endif
                                map (derefToExp s) ds
+derefToExp s (DerefGetField x f) =
+#if MIN_VERSION_template_haskell(2,18,0)
+    GetFieldE (derefToExp s x) f
+#else
+    error "Your compiler doesn't support OverloadedRecordDot"
+#endif
 
 -- FIXME shouldn't we use something besides a list here?
 flattenDeref :: Deref -> Maybe [String]
diff --git a/shakespeare.cabal b/shakespeare.cabal
--- a/shakespeare.cabal
+++ b/shakespeare.cabal
@@ -1,5 +1,5 @@
 name:            shakespeare
-version:         2.0.30
+version:         2.1.0
 license:         MIT
 license-file:    LICENSE
 author:          Michael Snoyman <michael@snoyman.com>
diff --git a/test/Text/Shakespeare/BaseSpec.hs b/test/Text/Shakespeare/BaseSpec.hs
--- a/test/Text/Shakespeare/BaseSpec.hs
+++ b/test/Text/Shakespeare/BaseSpec.hs
@@ -33,6 +33,25 @@
             (DerefBranch (DerefIdent (Ident "+")) (DerefIdent (Ident "a")))
             (DerefIdent (Ident "b"))))
 
+  it "parseDeref parse expressions with record dot" $ do
+    runParser parseDeref () "" "x.y" `shouldBe`
+      Right (DerefGetField (DerefIdent (Ident "x")) "y")
+
+  it "parseDeref parse expressions with multiple record dots" $ do
+    runParser parseDeref () "" "x.y.z" `shouldBe`
+      Right (DerefGetField (DerefGetField (DerefIdent (Ident "x")) "y") "z")
+
+  it "parseDeref dot surrounded by whitespace" $ do
+    runParser parseDeref () "" "x . y" `shouldBe`
+      Right
+        (DerefBranch
+          (DerefBranch (DerefIdent (Ident ".")) (DerefIdent (Ident "x")))
+          (DerefIdent (Ident "y")))
+
+  it "parseDeref parse expressions with parenthesized record dot" $ do
+    runParser parseDeref () "" "(x).y" `shouldBe`
+      Right (DerefGetField (DerefIdent (Ident "x")) "y")
+
   it "preFilter off" $ do
     preFilterN defaultShakespeareSettings template
       `shouldReturn` template
diff --git a/test/Text/Shakespeare/TextSpec.hs b/test/Text/Shakespeare/TextSpec.hs
--- a/test/Text/Shakespeare/TextSpec.hs
+++ b/test/Text/Shakespeare/TextSpec.hs
@@ -1,7 +1,10 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE QuasiQuotes #-}
 {-# LANGUAGE TemplateHaskell #-}
 module Text.Shakespeare.TextSpec (spec) where
 
+import HamletTestTypes (ARecord(..))
+
 import Test.HUnit hiding (Test)
 import Test.Hspec
 
@@ -122,6 +125,12 @@
       let val = 2 :: Int
       let bld = [builderQQ|#{ show val }|]
       simpT "2" $ toLazyText [builderQQ|^{ bld }|]
+    
+#if MIN_VERSION_template_haskell(2,18,0)
+    it "record dot" $ do
+      let z = ARecord 22 True
+      telper "221" [text|#{z.field1}#{fromEnum z.field2}|]
+#endif
 
 simpT :: String -> TL.Text -> Assertion
 simpT a b = nocrlf (pack a) @=? nocrlf (TL.toStrict b)
