diff --git a/samples/control-custom-state/README.md b/samples/control-custom-state/README.md
new file mode 100644
index 00000000..23e60cba
--- /dev/null
+++ b/samples/control-custom-state/README.md
@@ -0,0 +1,41 @@
+# Google Maps JavaScript Sample
+
+## control-custom-state
+
+This example demonstrates adding controls that store state.
+
+## Setup
+
+### Before starting run:
+
+`npm i`
+
+### Run an example on a local web server
+
+`cd samples/control-custom-state`
+`npm start`
+
+### Build an individual example
+
+`cd samples/control-custom-state`
+`npm run build`
+
+From 'samples':
+
+`npm run build --workspace=control-custom-state/`
+
+### Build all of the examples.
+
+From 'samples':
+
+`npm run build-all`
+
+### Run lint to check for problems
+
+`cd samples/control-custom-state`
+`npx eslint index.ts`
+
+## Feedback
+
+For feedback related to this sample, please open a new issue on
+[GitHub](https://github.com/googlemaps-samples/js-api-samples/issues).
diff --git a/samples/control-custom-state/index.html b/samples/control-custom-state/index.html
new file mode 100644
index 00000000..db7b8bd8
--- /dev/null
+++ b/samples/control-custom-state/index.html
@@ -0,0 +1,39 @@
+
+
+
+
+
+ Adding State to Controls
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/control-custom-state/index.ts b/samples/control-custom-state/index.ts
new file mode 100755
index 00000000..3b06ba3b
--- /dev/null
+++ b/samples/control-custom-state/index.ts
@@ -0,0 +1,43 @@
+/**
+ * @license
+ * Copyright 2026 Google LLC. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+// [START maps_control_custom_state]
+let innerMap;
+const mapElement = document.querySelector('gmp-map') as google.maps.MapElement;
+
+let center: google.maps.LatLngLiteral = { lat: 41.85, lng: -87.65 };
+
+async function initMap() {
+ (await google.maps.importLibrary('maps')) as google.maps.MapsLibrary;
+
+ innerMap = mapElement.innerMap;
+
+ // Get the button UI elements.
+ const setCenterButton = document.getElementById('btnCenterMap') as HTMLInputElement;
+ const resetCenterButton = document.getElementById('btnSetCenter') as HTMLInputElement;
+
+ // [START maps_control_custom_state_event_listeners]
+ // Set up the click event listener for the 'Center Map' button. Set the map
+ // to the currently stored center.
+ setCenterButton.addEventListener('click', () => {
+ const currentCenter = center;
+ innerMap.setCenter(currentCenter);
+ });
+
+ // Set up the click event listener for 'Set Center': Set the center of
+ // the control to the current center of the map.
+ resetCenterButton.addEventListener('click', () => {
+ const newCenter = innerMap.getCenter();
+
+ if (newCenter) {
+ center = newCenter;
+ }
+ });
+ // [END maps_control_custom_state_event_listeners]
+}
+
+initMap();
+// [END maps_control_custom_state]
diff --git a/samples/control-custom-state/package.json b/samples/control-custom-state/package.json
new file mode 100644
index 00000000..05df4547
--- /dev/null
+++ b/samples/control-custom-state/package.json
@@ -0,0 +1,14 @@
+{
+ "name": "@js-api-samples/control-custom-state",
+ "version": "1.0.0",
+ "scripts": {
+ "build": "tsc && bash ../jsfiddle.sh control-custom-state && bash ../app.sh control-custom-state && bash ../docs.sh control-custom-state && npm run build:vite --workspace=. && bash ../dist.sh control-custom-state",
+ "test": "tsc && npm run build:vite --workspace=.",
+ "start": "tsc && vite build --base './' && vite",
+ "build:vite": "vite build --base './'",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+
+ }
+}
diff --git a/samples/control-custom-state/style.css b/samples/control-custom-state/style.css
new file mode 100644
index 00000000..43f7a20e
--- /dev/null
+++ b/samples/control-custom-state/style.css
@@ -0,0 +1,39 @@
+/**
+ * @license
+ * Copyright 2026 Google LLC. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+/* [START maps_control_custom_state] */
+
+/*
+ * Optional: Makes the sample page fill the window.
+ */
+html,
+body {
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+#btnCenterMap,
+#btnSetCenter {
+ background-color: #fff;
+ border: 2px solid #fff;
+ border-radius: 3px;
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
+ cursor: pointer;
+ float: left;
+ margin-bottom: 22px;
+ margin-top: 5px;
+ text-align: center;
+ color: rgb(25, 25, 25);
+ font-family: Roboto, Arial, sans-serif;
+ font-size: 15px;
+ line-height: 25px;
+}
+
+#btnSetCenter {
+ margin-left: 12px;
+}
+
+/* [END maps_control_custom_state] */
\ No newline at end of file
diff --git a/samples/control-custom-state/tsconfig.json b/samples/control-custom-state/tsconfig.json
new file mode 100644
index 00000000..366aabb0
--- /dev/null
+++ b/samples/control-custom-state/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "compilerOptions": {
+ "module": "esnext",
+ "target": "esnext",
+ "strict": true,
+ "noImplicitAny": false,
+ "lib": [
+ "es2015",
+ "esnext",
+ "es6",
+ "dom",
+ "dom.iterable"
+ ],
+ "moduleResolution": "Node",
+ "jsx": "preserve"
+ }
+}