diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,10 @@
 # ChangeLog for shakespeare
 
+### 2.0.27
+
+* Change how embedded templates are located by the compiler. Relative files are now resolved using the Cabal project root, to fix builds of multi-project codebases. [#266](https://github.com/yesodweb/shakespeare/pull/266)
+* Change how messages are located by the compiler. The message directory is now resolved using the Cabal project root, to fix builds of multi-project codebases. [#266](https://github.com/yesodweb/shakespeare/pull/266)
+
 ### 2.0.26
 
 * Support `@supports` [#263](https://github.com/yesodweb/shakespeare/pull/263)
diff --git a/Text/Shakespeare/Base.hs b/Text/Shakespeare/Base.hs
--- a/Text/Shakespeare/Base.hs
+++ b/Text/Shakespeare/Base.hs
@@ -30,6 +30,7 @@
 import Language.Haskell.TH.Syntax
 import Language.Haskell.TH (appE)
 import Data.Char (isUpper, isSymbol, isPunctuation, isAscii)
+import Data.FileEmbed (makeRelativeToProject)
 import Text.ParserCombinators.Parsec
 import Text.Parsec.Prim (Parsec)
 import Data.List (intercalate)
@@ -283,11 +284,16 @@
 --
 -- @since 2.0.19
 readFileQ :: FilePath -> Q String
-readFileQ fp = qRunIO (readUtf8FileString fp)
+readFileQ rawFp = do
+  fp <- makeRelativeToProject rawFp
+  qRunIO (readUtf8FileString fp)
 
 -- | Embed file's content, converting newlines
 -- and track file via ghc dependencies, recompiling on changes
 --
 -- @since 2.0.19
 readFileRecompileQ :: FilePath -> Q String
-readFileRecompileQ fp = addDependentFile fp >> readFileQ fp
+readFileRecompileQ rawFp = do
+  fp <- makeRelativeToProject rawFp
+  addDependentFile fp
+  qRunIO (readUtf8FileString fp)
diff --git a/Text/Shakespeare/I18N.hs b/Text/Shakespeare/I18N.hs
--- a/Text/Shakespeare/I18N.hs
+++ b/Text/Shakespeare/I18N.hs
@@ -66,6 +66,7 @@
 import Control.Monad (filterM, forM)
 import Data.Text (Text, pack, unpack)
 import System.Directory
+import Data.FileEmbed (makeRelativeToProject)
 import Data.Maybe (catMaybes)
 import Data.List (isSuffixOf, sortBy, foldl')
 import qualified Data.Map as Map
@@ -152,7 +153,8 @@
                 -> FilePath  -- ^ path to translation folder
                 -> Lang      -- ^ default lang
                 -> Q [Dec]
-mkMessageCommon genType prefix postfix master dt folder lang = do
+mkMessageCommon genType prefix postfix master dt rawFolder lang = do
+    folder <- makeRelativeToProject rawFolder
     files <- qRunIO $ getDirectoryContents folder
     let files' = filter (`notElem` [".", ".."]) files
     (filess, contents) <- qRunIO $ fmap (unzip . catMaybes) $ mapM (loadLang folder) files'
diff --git a/shakespeare.cabal b/shakespeare.cabal
--- a/shakespeare.cabal
+++ b/shakespeare.cabal
@@ -1,5 +1,5 @@
 name:            shakespeare
-version:         2.0.26
+version:         2.0.27
 license:         MIT
 license-file:    LICENSE
 author:          Michael Snoyman <michael@snoyman.com>
@@ -49,6 +49,7 @@
                    , blaze-markup
                    , blaze-html
                    , exceptions
+                   , file-embed       >= 0.0.1   && < 0.1
                    , transformers
                    , vector
                    , unordered-containers
