diff --git a/.crafter/screenshots/directions.png b/.crafter/screenshots/directions.png
new file mode 100644
index 0000000..67a35b5
Binary files /dev/null and b/.crafter/screenshots/directions.png differ
diff --git a/.crafter/screenshots/place.png b/.crafter/screenshots/place.png
new file mode 100644
index 0000000..f02db6f
Binary files /dev/null and b/.crafter/screenshots/place.png differ
diff --git a/.crafter/screenshots/streetview.png b/.crafter/screenshots/streetview.png
new file mode 100644
index 0000000..ef7c16e
Binary files /dev/null and b/.crafter/screenshots/streetview.png differ
diff --git a/authoring/content-types/component/googlemaps/config.xml b/authoring/content-types/component/googlemaps/config.xml
new file mode 100644
index 0000000..51df44d
--- /dev/null
+++ b/authoring/content-types/component/googlemaps/config.xml
@@ -0,0 +1,18 @@
+
+
+
+ simple
+ NOT-USED-BY-SIMPLE-FORM-ENGINE
+ xml
+ false
+ false
+ false
+
+ false
+ thumbnail.png
+
+
+ ^/site/website.*
+
+
+
diff --git a/authoring/content-types/component/googlemaps/controller.groovy b/authoring/content-types/component/googlemaps/controller.groovy
new file mode 100644
index 0000000..bb9b8c4
--- /dev/null
+++ b/authoring/content-types/component/googlemaps/controller.groovy
@@ -0,0 +1,13 @@
+import scripts.libs.CommonLifecycleApi;
+
+def contentLifecycleParams =[:];
+contentLifecycleParams.site = site;
+contentLifecycleParams.path = path;
+contentLifecycleParams.user = user;
+contentLifecycleParams.contentType = contentType;
+contentLifecycleParams.contentLifecycleOperation = contentLifecycleOperation;
+contentLifecycleParams.contentLoader = contentLoader;
+contentLifecycleParams.applicationContext = applicationContext;
+
+def controller = new CommonLifecycleApi(contentLifecycleParams);
+controller.execute();
diff --git a/authoring/content-types/component/googlemaps/form-definition.xml b/authoring/content-types/component/googlemaps/form-definition.xml
new file mode 100644
index 0000000..cc99deb
--- /dev/null
+++ b/authoring/content-types/component/googlemaps/form-definition.xml
@@ -0,0 +1,1150 @@
+
diff --git a/authoring/content-types/component/googlemaps/thumbnail.png b/authoring/content-types/component/googlemaps/thumbnail.png
new file mode 100644
index 0000000..f02db6f
Binary files /dev/null and b/authoring/content-types/component/googlemaps/thumbnail.png differ
diff --git a/craftercms-plugin.yaml b/craftercms-plugin.yaml
new file mode 100644
index 0000000..d4cb269
--- /dev/null
+++ b/craftercms-plugin.yaml
@@ -0,0 +1,71 @@
+# MIT License
+#
+# Copyright (c) 2018-2021 Crafter Software Corporation. All Rights Reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+# The version of the format for this file
+descriptorVersion: 2
+
+# Describe the plugin
+plugin:
+ type: site
+ id: org.craftercms.plugin.google.maps
+ name: Google Maps
+ tags:
+ - web
+ - google
+ - maps
+ version:
+ major: 1
+ minor: 0
+ patch: 0
+ description: A plugin to add Google Maps to a site
+ website:
+ name: Google Maps Plugin
+ url: https://github.com/craftercms/googlemaps-plugin
+ media:
+ screenshots:
+ - title: Place
+ description: Google Maps in place mode
+ url: https://raw.githubusercontent.com/craftercms/googlemaps-plugin/master/.crafter/screenshot/place.png
+ - title: Directions
+ description: Google Maps in directions mode
+ url: https://raw.githubusercontent.com/craftercms/googlemaps-plugin/master/.crafter/screenshot/directions.png
+ - title: Street View
+ description: Google Maps in Street View mode
+ url: https://raw.githubusercontent.com/craftercms/googlemaps-plugin/master/.crafter/screenshot/streetview.png
+ developer:
+ company:
+ name: Crafter Software
+ email: info@craftersoftware.com
+ url: https://craftersoftware.com
+ build:
+ id: c3d2a5444e6a24b5e0481d6ba87901d0b02716c8
+ date: 2021-07-30T00:00:00Z
+ license:
+ name: MIT
+ url: https://opensource.org/licenses/MIT
+ crafterCmsVersions:
+ - major: 4
+ minor: 0
+ patch: 0
+ crafterCmsEditions:
+ - community
+ - enterprise
diff --git a/delivery/templates/googlemaps.ftl b/delivery/templates/googlemaps.ftl
new file mode 100644
index 0000000..ec8c523
--- /dev/null
+++ b/delivery/templates/googlemaps.ftl
@@ -0,0 +1,85 @@
+<#import "/templates/system/common/crafter.ftl" as crafter />
+
+<#assign apiKey = siteConfig.getString("plugins.googleMaps.apiKey")/>
+<#assign params = []/>
+
+<#if contentModel.center_s?has_content>
+ <#assign params += ["center=" + contentModel.center_s]/>
+#if>
+
+<#if contentModel.zoom_i?has_content>
+ <#assign params += ["zoom=" + contentModel.zoom_i]/>
+#if>
+
+<#if contentModel.mapType_s?has_content>
+ <#assign params += ["maptype=" + contentModel.mapType_s]/>
+#if>
+
+<#if contentModel.language_s?has_content>
+ <#assign params += ["language=" + contentModel.language_s]/>
+#if>
+
+<#if contentModel.region_s?has_content>
+ <#assign params += ["region=" + contentModel.region_s]/>
+#if>
+
+<#switch contentModel.mapMode_s>
+ <#case "place">
+ <#if contentModel.markerLocation_s?has_content>
+ <#assign params += ["q=" + contentModel.markerLocation_s]/>
+ #if>
+ <#break>
+ <#case "directions">
+ <#if contentModel.origin_s?has_content>
+ <#assign params += ["origin=" + contentModel.origin_s]/>
+ #if>
+ <#if contentModel.destination_s?has_content>
+ <#assign params += ["destination=" + contentModel.destination_s]/>
+ #if>
+ <#if contentModel.waypoints_s?has_content>
+ <#assign params += ["waypoints=" + contentModel.waypoints_s]/>
+ #if>
+ <#if contentModel.mode_s?has_content>
+ <#assign params += ["mode=" + contentModel.mode_s]/>
+ #if>
+ <#if contentModel.avoid_s?has_content>
+ <#assign params += ["avoid=" + contentModel.avoid_s]/>
+ #if>
+ <#if contentModel.units_s?has_content>
+ <#assign params += ["units=" + contentModel.units_s]/>
+ #if>
+ <#break>
+ <#case "streetview">
+ <#if contentModel.panoramaId_s?has_content>
+ <#assign params += ["pano=" + contentModel.panoramaId_s]/>
+ #if>
+ <#if contentModel.panoramaLocation_s?has_content>
+ <#assign params += ["location=" + contentModel.panoramaLocation_s]/>
+ #if>
+ <#if contentModel.heading_i?has_content>
+ <#assign params += ["heading=" + contentModel.heading_i]/>
+ #if>
+ <#if contentModel.pitch_i?has_content>
+ <#assign params += ["pitch=" + contentModel.pitch_i]/>
+ #if>
+ <#if contentModel.fov_i?has_content>
+ <#assign params += ["fov=" + contentModel.fov_i]/>
+ #if>
+ <#break>
+ <#case "search">
+ <#if contentModel.markerLocation_s?has_content>
+ <#assign params += ["q=" + contentModel.markerLocation_s]/>
+ #if>
+ <#break>
+#switch>
+
+<#-- TODO: Handle page builder events to make sure the component is always editable -->
+<@crafter.componentRootTag>
+ <@crafter.iframe
+ allowfullscreen="true"
+ width="${contentModel.width_s}"
+ height="${contentModel.height_s}"
+ frameborder="0" style="border:0"
+ src="https://www.google.com/maps/embed/v1/${contentModel.mapMode_s}?key=${apiKey}&${params?join('&')}"
+ />
+@crafter.componentRootTag>
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..7aa2434
--- /dev/null
+++ b/readme.md
@@ -0,0 +1,27 @@
+# Google Maps Plugin for Crafter CMS
+
+This is a highly configurable plugin to add Google Maps to your site.
+
+# Installation
+
+The plugin can be installed to your site from the Crafter CMS Marketplace
+
+# Setup
+
+After the plugin has been installed you need to setup your Google Maps API Key by adding the following snippet in
+your site configuration:
+
+```xml
+
+
+ ...
+
+
+```
+
+# Usage
+
+Once the API Key is properly configured you can create any number of Google Maps components as needed. Each instance
+of the component can be configured with any of the properties supported by Google Maps, for more information about
+the options see the
+[official docs](https://developers.google.com/maps/documentation/embed/embedding-map#choosing_map_modes).