add config throw_missing_includes, search_in_files
diff --git a/README.md b/README.md
index af79a45..58c9c2f 100644
--- a/README.md
+++ b/README.md
@@ -178,17 +178,22 @@
 
 #### Includes
 
-You can either include other template files or already parsed templates.
+You can either include other in-memory templates or from the file system.
 ```.cpp
-// Other template files are included relative from the current file location
-render("{% include \"footer.html\" %}", data);
-
 // To include in-memory templates, add them to the environment first
 inja::Template content_template = env.parse("Hello {{ neighbour }}!");
 env.include_template("content", content_template);
 env.render("Content: {% include \"content\" %}", data); // "Content: Hello Peter!"
+
+// Other template files are included relative from the current file location
+render("{% include \"footer.html\" %}", data);
+
+// You can disable to search for templates in the file system via
+env.set_search_included_templates_in_files(false);
 ```
 
+Inja will throw an `inja::RenderError` if an included file is not found.
+
 ### Functions
 
 A few functions are implemented within the inja template syntax. They can be called with
diff --git a/include/inja/config.hpp b/include/inja/config.hpp
index 13f465d..12dd94a 100644
--- a/include/inja/config.hpp
+++ b/include/inja/config.hpp
@@ -50,6 +50,14 @@
  */
 struct ParserConfig {
   ElementNotation notation {ElementNotation::Dot};
+  bool search_included_templates_in_files {true};
+};
+
+/*!
+ * \brief Class for render configuration.
+ */
+struct RenderConfig {
+  bool throw_at_missing_includes {true};
 };
 
 } // namespace inja
diff --git a/include/inja/environment.hpp b/include/inja/environment.hpp
index d1a32aa..aa6058d 100644
--- a/include/inja/environment.hpp
+++ b/include/inja/environment.hpp
@@ -26,6 +26,16 @@
  * \brief Class for changing the configuration.
  */
 class Environment {
+  std::string input_path;
+  std::string output_path;
+
+  LexerConfig lexer_config;
+  ParserConfig parser_config;
+  RenderConfig render_config;
+
+  FunctionStorage function_storage;
+  TemplateStorage template_storage;
+
 public:
   Environment() : Environment("") {}
 
@@ -76,6 +86,16 @@
     parser_config.notation = notation;
   }
 
+  /// Sets the element notation syntax
+  void set_search_included_templates_in_files(bool search_in_files) {
+    parser_config.search_included_templates_in_files = search_in_files;
+  }
+
+  /// Sets whether a missing include will throw an error
+  void set_throw_at_missing_includes(bool will_throw) {
+    render_config.throw_at_missing_includes = will_throw;
+  }
+
   Template parse(nonstd::string_view input) {
     Parser parser(parser_config, lexer_config, template_storage);
     return parser.parse(input);
@@ -127,7 +147,7 @@
   }
 
   std::ostream &render_to(std::ostream &os, const Template &tmpl, const json &data) {
-    Renderer(template_storage, function_storage).render_to(os, tmpl, data);
+    Renderer(render_config, template_storage, function_storage).render_to(os, tmpl, data);
     return os;
   }
 
@@ -154,16 +174,6 @@
   void include_template(const std::string &name, const Template &tmpl) {
     template_storage[name] = tmpl;
   }
-
-private:
-  std::string input_path;
-  std::string output_path;
-
-  LexerConfig lexer_config;
-  ParserConfig parser_config;
-
-  FunctionStorage function_storage;
-  TemplateStorage template_storage;
 };
 
 /*!
diff --git a/include/inja/parser.hpp b/include/inja/parser.hpp
index 6f766d5..5da97d8 100644
--- a/include/inja/parser.hpp
+++ b/include/inja/parser.hpp
@@ -475,7 +475,7 @@
       }
       // sys::path::remove_dots(pathname, true, sys::path::Style::posix);
 
-      if (template_storage.find(pathname) == template_storage.end()) {
+      if (config.search_included_templates_in_files && template_storage.find(pathname) == template_storage.end()) {
         Template include_template = parse_template(pathname);
         template_storage.emplace(pathname, include_template);
       }
diff --git a/include/inja/renderer.hpp b/include/inja/renderer.hpp
index dea43e9..b4a62c8 100644
--- a/include/inja/renderer.hpp
+++ b/include/inja/renderer.hpp
@@ -11,6 +11,7 @@
 
 #include <nlohmann/json.hpp>
 
+#include "config.hpp"
 #include "exceptions.hpp"
 #include "node.hpp"
 #include "template.hpp"
@@ -176,9 +177,11 @@
   std::vector<const json *> m_tmp_args;
   json m_tmp_val;
 
+  RenderConfig config;
+
 public:
-  Renderer(const TemplateStorage &included_templates, const FunctionStorage &callbacks)
-      : template_storage(included_templates), function_storage(callbacks) {
+  Renderer(const RenderConfig& config, const TemplateStorage &included_templates, const FunctionStorage &callbacks)
+      : config(config), template_storage(included_templates), function_storage(callbacks) {
     m_stack.reserve(16);
     m_tmp_args.reserve(4);
     m_loop_stack.reserve(16);
@@ -471,10 +474,14 @@
         break;
       }
       case Node::Op::Include: {
-        auto sub_renderer = Renderer(template_storage, function_storage);
+        auto sub_renderer = Renderer(config, template_storage, function_storage);
         auto include_name = get_imm(node)->get_ref<const std::string &>();
-        auto included_template = template_storage.find(include_name)->second;
-        sub_renderer.render_to(os, included_template, *m_data, m_loop_data);
+        auto included_template_it = template_storage.find(include_name);
+        if (included_template_it != template_storage.end()) {
+          sub_renderer.render_to(os, included_template_it->second, *m_data, m_loop_data);
+        } else if (config.throw_at_missing_includes) {
+          throw_renderer_error("include '" + include_name + "' not found", node);
+        }
         break;
       }
       case Node::Op::Callback: {
diff --git a/single_include/inja/inja.hpp b/single_include/inja/inja.hpp
index 20bff7e..65eda83 100644
--- a/single_include/inja/inja.hpp
+++ b/single_include/inja/inja.hpp
@@ -1488,6 +1488,14 @@
  */
 struct ParserConfig {
   ElementNotation notation {ElementNotation::Dot};
+  bool search_included_templates_in_files {true};
+};
+
+/*!
+ * \brief Class for render configuration.
+ */
+struct RenderConfig {
+  bool throw_at_missing_includes {true};
 };
 
 } // namespace inja
@@ -2760,7 +2768,7 @@
       }
       // sys::path::remove_dots(pathname, true, sys::path::Style::posix);
 
-      if (template_storage.find(pathname) == template_storage.end()) {
+      if (config.search_included_templates_in_files && template_storage.find(pathname) == template_storage.end()) {
         Template include_template = parse_template(pathname);
         template_storage.emplace(pathname, include_template);
       }
@@ -2910,6 +2918,8 @@
 
 #include <nlohmann/json.hpp>
 
+// #include "config.hpp"
+
 // #include "exceptions.hpp"
 
 // #include "node.hpp"
@@ -3079,9 +3089,11 @@
   std::vector<const json *> m_tmp_args;
   json m_tmp_val;
 
+  RenderConfig config;
+
 public:
-  Renderer(const TemplateStorage &included_templates, const FunctionStorage &callbacks)
-      : template_storage(included_templates), function_storage(callbacks) {
+  Renderer(const RenderConfig& config, const TemplateStorage &included_templates, const FunctionStorage &callbacks)
+      : config(config), template_storage(included_templates), function_storage(callbacks) {
     m_stack.reserve(16);
     m_tmp_args.reserve(4);
     m_loop_stack.reserve(16);
@@ -3374,10 +3386,14 @@
         break;
       }
       case Node::Op::Include: {
-        auto sub_renderer = Renderer(template_storage, function_storage);
+        auto sub_renderer = Renderer(config, template_storage, function_storage);
         auto include_name = get_imm(node)->get_ref<const std::string &>();
-        auto included_template = template_storage.find(include_name)->second;
-        sub_renderer.render_to(os, included_template, *m_data, m_loop_data);
+        auto included_template_it = template_storage.find(include_name);
+        if (included_template_it != template_storage.end()) {
+          sub_renderer.render_to(os, included_template_it->second, *m_data, m_loop_data);
+        } else if (config.throw_at_missing_includes) {
+          throw_renderer_error("include '" + include_name + "' not found", node);
+        }
         break;
       }
       case Node::Op::Callback: {
@@ -3521,6 +3537,16 @@
  * \brief Class for changing the configuration.
  */
 class Environment {
+  std::string input_path;
+  std::string output_path;
+
+  LexerConfig lexer_config;
+  ParserConfig parser_config;
+  RenderConfig render_config;
+
+  FunctionStorage function_storage;
+  TemplateStorage template_storage;
+
 public:
   Environment() : Environment("") {}
 
@@ -3571,6 +3597,16 @@
     parser_config.notation = notation;
   }
 
+  /// Sets the element notation syntax
+  void set_search_included_templates_in_files(bool search_in_files) {
+    parser_config.search_included_templates_in_files = search_in_files;
+  }
+
+  /// Sets whether a missing include will throw an error
+  void set_throw_at_missing_includes(bool will_throw) {
+    render_config.throw_at_missing_includes = will_throw;
+  }
+
   Template parse(nonstd::string_view input) {
     Parser parser(parser_config, lexer_config, template_storage);
     return parser.parse(input);
@@ -3622,7 +3658,7 @@
   }
 
   std::ostream &render_to(std::ostream &os, const Template &tmpl, const json &data) {
-    Renderer(template_storage, function_storage).render_to(os, tmpl, data);
+    Renderer(render_config, template_storage, function_storage).render_to(os, tmpl, data);
     return os;
   }
 
@@ -3649,16 +3685,6 @@
   void include_template(const std::string &name, const Template &tmpl) {
     template_storage[name] = tmpl;
   }
-
-private:
-  std::string input_path;
-  std::string output_path;
-
-  LexerConfig lexer_config;
-  ParserConfig parser_config;
-
-  FunctionStorage function_storage;
-  TemplateStorage template_storage;
 };
 
 /*!
diff --git a/test/unit-files.cpp b/test/unit-files.cpp
index b30d9d6..e8fa1b0 100644
--- a/test/unit-files.cpp
+++ b/test/unit-files.cpp
@@ -73,3 +73,12 @@
     CHECK(env_result.load_file("global-path-result.txt") == "Hello Jeff.");
   }
 }
+
+TEST_CASE("include-without-local-files") {
+  inja::Environment env {test_file_directory};
+  env.set_search_included_templates_in_files(false);
+
+  SUBCASE("html") {
+    CHECK_THROWS_WITH(env.render_file_with_json_file("html/template.txt", "html/data.json"), "[inja.exception.render_error] (at 21:1) include '../test/data/html/header.txt' not found");
+  }
+}