diff --git a/docs/API-Reference/command/Commands.md b/docs/API-Reference/command/Commands.md
index 6e7a0950a7..d2f6748070 100644
--- a/docs/API-Reference/command/Commands.md
+++ b/docs/API-Reference/command/Commands.md
@@ -164,6 +164,12 @@ Reloads live preview
 ## FILE\_LIVE\_HIGHLIGHT
 Toggles live highlight
 
+**Kind**: global variable  
+
+
+## FILE\_LIVE\_WORD\_NAVIGATION
+Toggles word-level navigation in live preview
+
 **Kind**: global variable  
 
 
diff --git a/src-node/package-lock.json b/src-node/package-lock.json
index 6177376876..6183efc95f 100644
--- a/src-node/package-lock.json
+++ b/src-node/package-lock.json
@@ -1,12 +1,12 @@
 {
     "name": "@phcode/node-core",
-    "version": "4.1.0-0",
+    "version": "4.1.1-0",
     "lockfileVersion": 3,
     "requires": true,
     "packages": {
         "": {
             "name": "@phcode/node-core",
-            "version": "4.1.0-0",
+            "version": "4.1.1-0",
             "license": "GNU-AGPL3.0",
             "dependencies": {
                 "@phcode/fs": "^3.0.1",
diff --git a/src/LiveDevelopment/BrowserScripts/LiveDevProtocolRemote.js b/src/LiveDevelopment/BrowserScripts/LiveDevProtocolRemote.js
index 0731a1f86e..ec555860ae 100644
--- a/src/LiveDevelopment/BrowserScripts/LiveDevProtocolRemote.js
+++ b/src/LiveDevelopment/BrowserScripts/LiveDevProtocolRemote.js
@@ -382,12 +382,146 @@
     }
 
 
+    /**
+    * Gets the word at the clicked position along with additional information
+    * @param {Element} element - The element that was clicked
+    * @param {MouseEvent} event - The click event
+    * @return {Object|null} - Object containing the word and additional info, or null if not found
+    */
+    function getClickedWord(element, event) {
+
+        // Try to find the clicked position within the element
+        const range = document.caretRangeFromPoint(event.clientX, event.clientY);
+        if (!range) {
+            return null;
+        }
+
+        const textNode = range.startContainer;
+        const offset = range.startOffset;
+
+        // Check if we have a text node
+        if (textNode.nodeType !== Node.TEXT_NODE) {
+
+            // If the element itself contains text, try to extract a word from it
+            if (element.textContent && element.textContent.trim()) {
+                const text = element.textContent.trim();
+
+                // Simple word extraction - get the first word
+                const match = text.match(/\b(\w+)\b/);
+                if (match) {
+                    const word = match[1];
+
+                    // Since we're just getting the first word, it's the first occurrence
+                    return {
+                        word: word,
+                        occurrenceIndex: 0,
+                        context: text.substring(0, Math.min(40, text.length))
+                    };
+                }
+            }
+
+            return null;
+        }
+
+        const nodeText = textNode.textContent;
+
+        // Function to extract a word and its occurrence index
+        function extractWordAndOccurrence(text, wordStart, wordEnd) {
+            const word = text.substring(wordStart, wordEnd);
+
+            // Calculate which occurrence of this word it is
+            const textBeforeWord = text.substring(0, wordStart);
+            const regex = new RegExp("\\b" + word + "\\b", "g");
+            let occurrenceIndex = 0;
+            let match;
+
+            while ((match = regex.exec(textBeforeWord)) !== null) {
+                occurrenceIndex++;
+            }
+
+
+            // Get context around the word (up to 20 chars before and after)
+            const contextStart = Math.max(0, wordStart - 20);
+            const contextEnd = Math.min(text.length, wordEnd + 20);
+            const context = text.substring(contextStart, contextEnd);
+
+            return {
+                word: word,
+                occurrenceIndex: occurrenceIndex,
+                context: context
+            };
+        }
+
+        // If we're at a space or the text is empty, try to find a nearby word
+        if (nodeText.length === 0 || (offset < nodeText.length && /\s/.test(nodeText[offset]))) {
+
+            // Look for the nearest word
+            let leftPos = offset - 1;
+            let rightPos = offset;
+
+            // Check to the left
+            while (leftPos >= 0 && /\s/.test(nodeText[leftPos])) {
+                leftPos--;
+            }
+
+            // Check to the right
+            while (rightPos < nodeText.length && /\s/.test(nodeText[rightPos])) {
+                rightPos++;
+            }
+
+            // If we found a non-space character to the left, extract that word
+            if (leftPos >= 0) {
+                let wordStart = leftPos;
+                while (wordStart > 0 && /\w/.test(nodeText[wordStart - 1])) {
+                    wordStart--;
+                }
+
+                return extractWordAndOccurrence(nodeText, wordStart, leftPos + 1);
+            }
+
+            // If we found a non-space character to the right, extract that word
+            if (rightPos < nodeText.length) {
+                let wordEnd = rightPos;
+                while (wordEnd < nodeText.length && /\w/.test(nodeText[wordEnd])) {
+                    wordEnd++;
+                }
+
+                return extractWordAndOccurrence(nodeText, rightPos, wordEnd);
+            }
+
+            return null;
+        }
+
+        // Find word boundaries
+        let startPos = offset;
+        let endPos = offset;
+
+        // Move start position to the beginning of the word
+        while (startPos > 0 && /\w/.test(nodeText[startPos - 1])) {
+            startPos--;
+        }
+
+        // Move end position to the end of the word
+        while (endPos < nodeText.length && /\w/.test(nodeText[endPos])) {
+            endPos++;
+        }
+
+
+        // Extract the word and its occurrence index
+        if (endPos > startPos) {
+            return extractWordAndOccurrence(nodeText, startPos, endPos);
+        }
+
+        return null;
+    }
+
     /**
     * Sends the message containing tagID which is being clicked
     * to the editor in order to change the cursor position to
     * the HTML tag corresponding to the clicked element.
     */
     function onDocumentClick(event) {
+
         // Get the user's current selection
         const selection = window.getSelection();
 
@@ -399,8 +533,14 @@
             return;
         }
         var element = event.target;
+
         if (element && element.hasAttribute('data-brackets-id')) {
-            MessageBroker.send({
+
+            // Get the clicked word and its information
+            const clickedWordInfo = getClickedWord(element, event);
+
+            // Prepare the message with the clicked word information
+            const message = {
                 "tagId": element.getAttribute('data-brackets-id'),
                 "nodeID": element.id,
                 "nodeClassList": element.classList,
@@ -408,7 +548,17 @@
                 "allSelectors": _getAllInheritedSelectorsInOrder(element),
                 "contentEditable": element.contentEditable === 'true',
                 "clicked": true
-            });
+            };
+
+            // Add word information if available
+            if (clickedWordInfo) {
+                message.clickedWord = clickedWordInfo.word;
+                message.wordContext = clickedWordInfo.context;
+                message.wordOccurrenceIndex = clickedWordInfo.occurrenceIndex;
+            }
+
+            MessageBroker.send(message);
+        } else {
         }
     }
     window.document.addEventListener("click", onDocumentClick);
diff --git a/src/LiveDevelopment/MultiBrowserImpl/protocol/LiveDevProtocol.js b/src/LiveDevelopment/MultiBrowserImpl/protocol/LiveDevProtocol.js
index f6b9c39108..75c2662bb1 100644
--- a/src/LiveDevelopment/MultiBrowserImpl/protocol/LiveDevProtocol.js
+++ b/src/LiveDevelopment/MultiBrowserImpl/protocol/LiveDevProtocol.js
@@ -147,31 +147,335 @@ define(function (require, exports, module) {
         }
     }
 
-    function _tagSelectedInLivePreview(tagId, nodeName, contentEditable, allSelectors) {
+    function _findWordInEditor(editor, word, nodeName, tagId, wordContext, wordOccurrenceIndex) {
+
+        if (!editor || !word) {
+
+            return false;
+        }
+
+        const codeMirror = editor._codeMirror;
+
+        // First try to find the word within the context of the clicked element
+        if (tagId) {
+
+            // Get the position of the tag in the editor
+            const tagPosition = HTMLInstrumentation.getPositionFromTagId(editor, parseInt(tagId, 10));
+
+            if (tagPosition) {
+                // Find the opening and closing tags to determine the element's content boundaries
+                let openTagEndLine = tagPosition.line;
+                let openTagEndCh = tagPosition.ch;
+                let closeTagStartLine = -1;
+                let closeTagStartCh = -1;
+
+                // Find the end of the opening tag (>)
+                let foundOpenTagEnd = false;
+                for (let line = openTagEndLine; line < codeMirror.lineCount() && !foundOpenTagEnd; line++) {
+                    const lineText = codeMirror.getLine(line);
+                    let startCh = (line === openTagEndLine) ? openTagEndCh : 0;
+
+                    const gtIndex = lineText.indexOf('>', startCh);
+                    if (gtIndex !== -1) {
+                        openTagEndLine = line;
+                        openTagEndCh = gtIndex + 1; // Position after the >
+                        foundOpenTagEnd = true;
+                    }
+                }
+
+                if (!foundOpenTagEnd) {
+                    return false;
+                }
+
+                // Check if this is a self-closing tag
+                const lineWithOpenTag = codeMirror.getLine(openTagEndLine);
+                const isSelfClosing = lineWithOpenTag.substring(0, openTagEndCh).includes('/>');
+
+                if (!isSelfClosing) {
+                    // Find the closing tag
+                    const closeTagRegex = new RegExp(`${nodeName}[^>]*>`, 'i');
+                    let searchStartPos = {line: openTagEndLine, ch: openTagEndCh};
+
+                    // Create a search cursor to find the closing tag
+                    const closeTagCursor = codeMirror.getSearchCursor(closeTagRegex, searchStartPos);
+                    if (closeTagCursor.findNext()) {
+                        closeTagStartLine = closeTagCursor.from().line;
+                        closeTagStartCh = closeTagCursor.from().ch;
+                    } else {
+                        // If we can't find the closing tag, we'll just search in a reasonable range after the opening tag
+                        closeTagStartLine = Math.min(openTagEndLine + 10, codeMirror.lineCount() - 1);
+                        closeTagStartCh = codeMirror.getLine(closeTagStartLine).length;
+                    }
+                } else {
+                    // For self-closing tags, there's no content to search
+                    return false;
+                }
+
+                // Prioritize finding the word by its occurrence index within the element
+                if (typeof wordOccurrenceIndex === 'number') {
+
+                    // Create a word regex that matches the exact word
+                    const wordRegex = new RegExp("\\b" + word + "\\b", "g");
+
+                    // Create a search cursor limited to the element's content
+                    const wordCursor = codeMirror.getSearchCursor(
+                        wordRegex,
+                        {line: openTagEndLine, ch: openTagEndCh},
+                        {line: closeTagStartLine, ch: closeTagStartCh}
+                    );
+
+                    let currentOccurrence = 0;
+                    let found = false;
+
+                    // Find the specific occurrence of the word
+                    while (wordCursor.findNext()) {
+                        if (currentOccurrence === wordOccurrenceIndex) {
+                            const wordPos = wordCursor.from();
+                            editor.setCursorPos(wordPos.line, wordPos.ch, true);
+                            found = true;
+                            break;
+                        }
+                        currentOccurrence++;
+                    }
+
+                    if (found) {
+                        return true;
+                    }
+
+                }
+
+                // If occurrence index search failed or no occurrence index available, try context as a fallback
+                if (wordContext) {
+
+                    // Escape special regex characters in the context and word
+                    const escapedContext = wordContext.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
+
+                    // Create a regex that matches the context
+                    const contextRegex = new RegExp(escapedContext, "g");
+
+                    // Create a search cursor limited to the element's content
+                    const contextCursor = codeMirror.getSearchCursor(
+                        contextRegex,
+                        {line: openTagEndLine, ch: openTagEndCh},
+                        {line: closeTagStartLine, ch: closeTagStartCh}
+                    );
+
+                    if (contextCursor.findNext()) {
+                        // Found the context within the element
+                        const contextPos = contextCursor.from();
+                        const contextText = codeMirror.getRange(
+                            contextCursor.from(),
+                            contextCursor.to()
+                        );
+
+                        // Find the position of the word within the context
+                        const wordIndex = wordContext.indexOf(word);
+                        if (wordIndex !== -1) {
+                            const wordPos = {
+                                line: contextPos.line,
+                                ch: contextPos.ch + wordIndex
+                            };
+
+                            editor.setCursorPos(wordPos.line, wordPos.ch, true);
+                            return true;
+                        }
+                    }
+                }
+
+                // If both occurrence index and context search failed, search for any occurrence of the word
+
+                // Create a word regex that matches the exact word
+                const wordRegex = new RegExp("\\b" + word + "\\b", "g");
+
+                // Create a search cursor limited to the element's content
+                const wordCursor = codeMirror.getSearchCursor(
+                    wordRegex,
+                    {line: openTagEndLine, ch: openTagEndCh},
+                    {line: closeTagStartLine, ch: closeTagStartCh}
+                );
+
+                // If we have an occurrence index, find the specific occurrence of the word
+                if (typeof wordOccurrenceIndex === 'number') {
+
+                    let currentOccurrence = 0;
+                    let found = false;
+
+                    // Find the specific occurrence of the word
+                    while (wordCursor.findNext()) {
+                        if (currentOccurrence === wordOccurrenceIndex) {
+                            const wordPos = wordCursor.from();
+                            editor.setCursorPos(wordPos.line, wordPos.ch, true);
+                            found = true;
+                            break;
+                        }
+                        currentOccurrence++;
+                    }
+
+                    if (found) {
+                        return true;
+                    }
+
+                }
+                // If no occurrence index or the specific occurrence wasn't found, just find the first occurrence
+                else {
+                    if (wordCursor.findNext()) {
+                        const wordPos = wordCursor.from();
+                        editor.setCursorPos(wordPos.line, wordPos.ch, true);
+                        return true;
+                    }
+                }
+
+                // If exact word search failed, try a more flexible search within the element
+
+                const flexWordRegex = new RegExp(word, "g");
+                const flexWordCursor = codeMirror.getSearchCursor(
+                    flexWordRegex,
+                    {line: openTagEndLine, ch: openTagEndCh},
+                    {line: closeTagStartLine, ch: closeTagStartCh}
+                );
+
+                if (flexWordCursor.findNext()) {
+                    const flexWordPos = flexWordCursor.from();
+                    editor.setCursorPos(flexWordPos.line, flexWordPos.ch, true);
+                    return true;
+                }
+            }
+        }
+
+        // If we couldn't find the word in the tag's context, try a document-wide search
+        // Prioritize finding the word by its occurrence index in the entire document
+        if (typeof wordOccurrenceIndex === 'number') {
+
+            // Create a word regex that matches the exact word
+            const wordRegex = new RegExp("\\b" + word + "\\b", "g");
+            const wordCursor = codeMirror.getSearchCursor(wordRegex);
+
+            let currentOccurrence = 0;
+            let found = false;
+
+            // Find the specific occurrence of the word
+            while (wordCursor.findNext()) {
+                if (currentOccurrence === wordOccurrenceIndex) {
+                    const wordPos = wordCursor.from();
+                    editor.setCursorPos(wordPos.line, wordPos.ch, true);
+                    found = true;
+                    break;
+                }
+                currentOccurrence++;
+            }
+
+            if (found) {
+                return true;
+            }
+
+        }
+
+        // If occurrence index search failed or no occurrence index available, try context as a fallback
+        if (wordContext) {
+
+            // Escape special regex characters in the context
+            const escapedContext = wordContext.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
+
+            // Create a regex that matches the context with the word
+            const contextRegex = new RegExp(escapedContext, "g");
+
+            const contextCursor = codeMirror.getSearchCursor(contextRegex);
+            let contextFound = contextCursor.findNext();
+
+            if (contextFound) {
+                // Find the position of the word within the context
+                const contextMatch = contextCursor.from();
+                const wordInContextIndex = wordContext.indexOf(word);
+
+                if (wordInContextIndex !== -1) {
+                    // Calculate the exact position of the word within the found context
+                    const line = contextMatch.line;
+                    const ch = contextMatch.ch + wordInContextIndex;
+
+                    editor.setCursorPos(line, ch, true);
+                    return true;
+                }
+            }
+        }
+
+        // If both occurrence index and context search failed, fall back to a simple search
+
+        // Try to find the first occurrence of the exact word
+        const wordRegex = new RegExp("\\b" + word + "\\b", "g");
+
+        const cursor = codeMirror.getSearchCursor(wordRegex);
+        let foundFirstOccurrence = cursor.findNext();
+
+        if (foundFirstOccurrence) {
+            const position = {line: cursor.from().line, ch: cursor.from().ch};
+            editor.setCursorPos(position.line, position.ch, true);
+            return true;
+        }
+
+        // If exact word not found, try a more flexible search
+        const flexibleRegex = new RegExp(word, "g");
+
+        const flexCursor = codeMirror.getSearchCursor(flexibleRegex);
+        let flexibleFound = flexCursor.findNext();
+
+        if (flexibleFound) {
+            const position = {line: flexCursor.from().line, ch: flexCursor.from().ch};
+            editor.setCursorPos(position.line, position.ch, true);
+            return true;
+        }
+
+        return false;
+    }
+
+    function _tagSelectedInLivePreview(tagId, nodeName, contentEditable, allSelectors, clickedWord, wordContext, wordOccurrenceIndex) {
+
         const highlightPref = PreferencesManager.getViewState("livedevHighlight");
-        if(!highlightPref){
-            // live preview highlight and reverse highlight feature is disabled
+        const wordNavPref = PreferencesManager.getViewState("livedevWordNavigation");
+
+
+        if(!highlightPref && !wordNavPref){
+            // Both live preview highlight and word navigation are disabled
             return;
         }
         const liveDoc = LiveDevMultiBrowser.getCurrentLiveDoc(),
             activeEditor = EditorManager.getActiveEditor(), // this can be an inline editor
             activeFullEditor = EditorManager.getCurrentFullEditor();
+
+
         const liveDocPath = liveDoc ? liveDoc.doc.file.fullPath : null,
             activeEditorPath = activeEditor ? activeEditor.document.file.fullPath : null,
             activeFullEditorPath = activeFullEditor ? activeFullEditor.document.file.fullPath : null;
+
         if(!liveDocPath){
             activeEditor && activeEditor.focus(); // restore focus from live preview
             return;
         }
         const allOpenFileCount = MainViewManager.getWorkingSetSize(MainViewManager.ALL_PANES);
+
         function selectInHTMLEditor(fullHtmlEditor) {
+
+            // If word navigation is enabled and we have a clicked word, try to find it
+            if (wordNavPref && clickedWord && fullHtmlEditor) {
+                const masterEditor = fullHtmlEditor.document._masterEditor || fullHtmlEditor;
+
+                const wordFound = _findWordInEditor(masterEditor, clickedWord, nodeName, tagId, wordContext, wordOccurrenceIndex);
+
+                if (wordFound) {
+                    _focusEditorIfNeeded(masterEditor, nodeName, contentEditable);
+                    return;
+                }
+            }
+
+            // Fall back to tag-based navigation if word navigation fails or is disabled
             const position = HTMLInstrumentation.getPositionFromTagId(fullHtmlEditor, parseInt(tagId, 10));
+
             if(position && fullHtmlEditor) {
                 const masterEditor = fullHtmlEditor.document._masterEditor || fullHtmlEditor;
                 masterEditor.setCursorPos(position.line, position.ch, true);
                 _focusEditorIfNeeded(masterEditor, nodeName, contentEditable);
             }
         }
+
         if(liveDocPath === activeFullEditorPath) {
             // if the active pane is the html being live previewed, select that.
             selectInHTMLEditor(activeFullEditor);
@@ -180,7 +484,18 @@ define(function (require, exports, module) {
             // then we dont need to open the html live doc. For less files, we dont check if its related as
             // its not directly linked usually and needs a compile step. so we just do a fuzzy search.
             _focusEditorIfNeeded(activeEditor, nodeName, contentEditable);
-            _searchAndCursorIfCSS(activeEditor, allSelectors, nodeName);
+
+            // Try word-level navigation first if enabled
+            if (wordNavPref && clickedWord) {
+                const wordFound = _findWordInEditor(activeEditor, clickedWord, nodeName, tagId, wordContext, wordOccurrenceIndex);
+                if (!wordFound) {
+                    // Fall back to CSS selector search if word not found
+                    _searchAndCursorIfCSS(activeEditor, allSelectors, nodeName);
+                }
+            } else {
+                // Use traditional CSS selector search
+                _searchAndCursorIfCSS(activeEditor, allSelectors, nodeName);
+            }
             // in this case, see if we need to do any css reverse highlight magic here
         } else if(!allOpenFileCount){
             // no open editor in any panes, then open the html file directly.
@@ -204,9 +519,11 @@ define(function (require, exports, module) {
      * @param {string} msg The message that was sent, in JSON string format
      */
     function _receive(clientId, msgStr) {
+
         var msg = JSON.parse(msgStr),
-            event = msg.method || "event",
             deferred;
+
+
         if (msg.id) {
             deferred = _responseDeferreds[msg.id];
             if (deferred) {
@@ -218,12 +535,13 @@ define(function (require, exports, module) {
                 }
             }
         } else if (msg.clicked && msg.tagId) {
-            _tagSelectedInLivePreview(msg.tagId, msg.nodeName, msg.contentEditable, msg.allSelectors);
+            _tagSelectedInLivePreview(msg.tagId, msg.nodeName, msg.contentEditable, msg.allSelectors,
+                                     msg.clickedWord, msg.wordContext, msg.wordOccurrenceIndex);
             exports.trigger(EVENT_LIVE_PREVIEW_CLICKED, msg);
         } else {
             // enrich received message with clientId
             msg.clientId = clientId;
-            exports.trigger(event, msg);
+            exports.trigger(msg.method || "event", msg);
         }
     }
 
@@ -295,13 +613,13 @@ define(function (require, exports, module) {
         _transport = transport;
 
         _transport
-            .on("connect.livedev", function (event, msg) {
+            .on("connect.livedev", function (_, msg) {
                 _connect(msg[0], msg[1]);
             })
-            .on("message.livedev", function (event, msg) {
+            .on("message.livedev", function (_, msg) {
                 _receive(msg[0], msg[1]);
             })
-            .on("close.livedev", function (event, msg) {
+            .on("close.livedev", function (_, msg) {
                 _close(msg[0]);
             });
         _transport.start();
@@ -386,7 +704,8 @@ define(function (require, exports, module) {
                     url: url,
                     text: text
                 }
-            }
+            },
+            clients
         );
     }
 
@@ -422,7 +741,7 @@ define(function (require, exports, module) {
             {
                 method: "Page.reload",
                 params: {
-                    ignoreCache: true
+                    ignoreCache: ignoreCache || true
                 }
             },
             clients
diff --git a/src/LiveDevelopment/main.js b/src/LiveDevelopment/main.js
index 7d85eeab5f..c63a8e1ed1 100644
--- a/src/LiveDevelopment/main.js
+++ b/src/LiveDevelopment/main.js
@@ -45,12 +45,14 @@ define(function main(require, exports, module) {
         EventDispatcher      = require("utils/EventDispatcher");
 
     const EVENT_LIVE_HIGHLIGHT_PREF_CHANGED = "liveHighlightPrefChange";
+    const EVENT_WORD_NAVIGATION_PREF_CHANGED = "wordNavigationPrefChange";
 
     var params = new UrlParams();
     var config = {
         experimental: false, // enable experimental features
         debug: true, // enable debug output and helpers
         highlight: true, // enable highlighting?
+        wordNavigation: false, // enable word-level navigation?
         highlightConfig: { // the highlight configuration for the Inspector
             borderColor:  {r: 255, g: 229, b: 153, a: 0.66},
             contentColor: {r: 111, g: 168, b: 220, a: 0.55},
@@ -227,6 +229,17 @@ define(function main(require, exports, module) {
         PreferencesManager.setViewState("livedevHighlight", config.highlight);
     }
 
+    function _updateWordNavigationCheckmark() {
+        CommandManager.get(Commands.FILE_LIVE_WORD_NAVIGATION).setChecked(config.wordNavigation);
+        exports.trigger(EVENT_WORD_NAVIGATION_PREF_CHANGED, config.wordNavigation);
+    }
+
+    function toggleWordNavigation() {
+        config.wordNavigation = !config.wordNavigation;
+        _updateWordNavigationCheckmark();
+        PreferencesManager.setViewState("livedevWordNavigation", config.wordNavigation);
+    }
+
     /** Setup window references to useful LiveDevelopment modules */
     function _setupDebugHelpers() {
         window.report = function report(params) { window.params = params; console.info(params); };
@@ -302,13 +315,22 @@ define(function main(require, exports, module) {
             _updateHighlightCheckmark();
         });
 
+    PreferencesManager.stateManager.definePreference("livedevWordNavigation", "boolean", false)
+        .on("change", function () {
+            config.wordNavigation = PreferencesManager.getViewState("livedevWordNavigation");
+            _updateWordNavigationCheckmark();
+        });
+
     config.highlight = PreferencesManager.getViewState("livedevHighlight");
+    config.wordNavigation = PreferencesManager.getViewState("livedevWordNavigation");
 
     // init commands
     CommandManager.register(Strings.CMD_LIVE_HIGHLIGHT, Commands.FILE_LIVE_HIGHLIGHT, togglePreviewHighlight);
+    CommandManager.register(Strings.CMD_LIVE_WORD_NAVIGATION, Commands.FILE_LIVE_WORD_NAVIGATION, toggleWordNavigation);
     CommandManager.register(Strings.CMD_RELOAD_LIVE_PREVIEW, Commands.CMD_RELOAD_LIVE_PREVIEW, _handleReloadLivePreviewCommand);
 
     CommandManager.get(Commands.FILE_LIVE_HIGHLIGHT).setEnabled(false);
+    CommandManager.get(Commands.FILE_LIVE_WORD_NAVIGATION).setEnabled(false);
 
     EventDispatcher.makeEventDispatcher(exports);
 
@@ -318,6 +340,7 @@ define(function main(require, exports, module) {
     exports.EVENT_LIVE_PREVIEW_CLICKED = MultiBrowserLiveDev.EVENT_LIVE_PREVIEW_CLICKED;
     exports.EVENT_LIVE_PREVIEW_RELOAD = MultiBrowserLiveDev.EVENT_LIVE_PREVIEW_RELOAD;
     exports.EVENT_LIVE_HIGHLIGHT_PREF_CHANGED = EVENT_LIVE_HIGHLIGHT_PREF_CHANGED;
+    exports.EVENT_WORD_NAVIGATION_PREF_CHANGED = EVENT_WORD_NAVIGATION_PREF_CHANGED;
 
     // Export public functions
     exports.openLivePreview = openLivePreview;
@@ -327,6 +350,7 @@ define(function main(require, exports, module) {
     exports.setLivePreviewPinned = setLivePreviewPinned;
     exports.setLivePreviewTransportBridge = setLivePreviewTransportBridge;
     exports.togglePreviewHighlight = togglePreviewHighlight;
+    exports.toggleWordNavigation = toggleWordNavigation;
     exports.getConnectionIds = MultiBrowserLiveDev.getConnectionIds;
     exports.getLivePreviewDetails = MultiBrowserLiveDev.getLivePreviewDetails;
 });
diff --git a/src/base-config/keyboard.json b/src/base-config/keyboard.json
index 8674ac0619..b7d08e13ea 100644
--- a/src/base-config/keyboard.json
+++ b/src/base-config/keyboard.json
@@ -31,6 +31,9 @@
     "file.previewHighlight":  [
         "Ctrl-Shift-C"
     ],
+    "file.previewWordNavigation":  [
+        "Ctrl-Shift-W"
+    ],
     "file.quit":  [
         "Ctrl-Q"
     ],
diff --git a/src/command/Commands.js b/src/command/Commands.js
index 2314c47e32..fa659fab5d 100644
--- a/src/command/Commands.js
+++ b/src/command/Commands.js
@@ -106,6 +106,9 @@ define(function (require, exports, module) {
     /** Toggles live highlight */
     exports.FILE_LIVE_HIGHLIGHT         = "file.previewHighlight";      // LiveDevelopment/main.js      _handlePreviewHighlightCommand()
 
+    /** Toggles word-level navigation in live preview */
+    exports.FILE_LIVE_WORD_NAVIGATION   = "file.previewWordNavigation"; // LiveDevelopment/main.js      toggleWordNavigation()
+
     /** Opens project settings */
     exports.FILE_PROJECT_SETTINGS       = "file.projectSettings";       // ProjectManager.js            _projectSettings()
 
diff --git a/src/extensionsIntegrated/Phoenix-live-preview/images/sprites.svg b/src/extensionsIntegrated/Phoenix-live-preview/images/sprites.svg
index 7c2005fa24..92b179e728 100644
--- a/src/extensionsIntegrated/Phoenix-live-preview/images/sprites.svg
+++ b/src/extensionsIntegrated/Phoenix-live-preview/images/sprites.svg
@@ -33,4 +33,13 @@