diff --git a/client/i18n/locales/english/intro.json b/client/i18n/locales/english/intro.json
index aa0c04e4286..701039a5fc0 100644
--- a/client/i18n/locales/english/intro.json
+++ b/client/i18n/locales/english/intro.json
@@ -3051,6 +3051,12 @@
"In this lesson you will learn how to search for substrings using the includes() method and how to extract portions of strings using the slice() method."
]
},
+ "workshop-string-inspector": {
+ "title": "Build a String Inspector",
+ "intro": [
+ "In this workshop, you will practice working with the includes() and slice() methods by building a string inspector."
+ ]
+ },
"lecture-working-with-string-formatting-methods": {
"title": "Working with String Formatting Methods",
"intro": [
diff --git a/client/src/pages/learn/full-stack-developer/workshop-string-inspector/index.md b/client/src/pages/learn/full-stack-developer/workshop-string-inspector/index.md
new file mode 100644
index 00000000000..bc85340a8a7
--- /dev/null
+++ b/client/src/pages/learn/full-stack-developer/workshop-string-inspector/index.md
@@ -0,0 +1,9 @@
+---
+title: Introduction to Build a String Inspector
+block: workshop-string-inspector
+superBlock: full-stack-developer
+---
+
+## Introduction to Build a String Inspector
+
+In this workshop, you will learn how to work with the `includes()` and `slice()` methods by building a string inspector.
diff --git a/curriculum/challenges/english/blocks/workshop-string-inspector/68e51d8f163d3f8b70f9c4e5.md b/curriculum/challenges/english/blocks/workshop-string-inspector/68e51d8f163d3f8b70f9c4e5.md
new file mode 100644
index 00000000000..3a2131cfeee
--- /dev/null
+++ b/curriculum/challenges/english/blocks/workshop-string-inspector/68e51d8f163d3f8b70f9c4e5.md
@@ -0,0 +1,42 @@
+---
+id: 68e51d8f163d3f8b70f9c4e5
+title: Step 1
+challengeType: 1
+dashedName: step-1
+---
+
+# --description--
+
+In this workshop, you will practice working with the `includes()` and `slice()` methods.
+
+To begin, create a variable named `fccSentence` and assign it the string `"freeCodeCamp is a great place to learn web development."`.
+
+# --hints--
+
+You should declare a variable named `fccSentence`.
+
+```js
+assert.exists(fccSentence);
+```
+
+Your `fccSentence` variable should be a string.
+
+```js
+assert.isString(fccSentence);
+```
+
+Your `fccSentence` variable should be assigned the string `"freeCodeCamp is a great place to learn web development."`.
+
+```js
+assert.strictEqual(fccSentence, "freeCodeCamp is a great place to learn web development.");
+```
+
+# --seed--
+
+## --seed-contents--
+
+```js
+--fcc-editable-region--
+
+--fcc-editable-region--
+```
diff --git a/curriculum/challenges/english/blocks/workshop-string-inspector/68e6172875008fea742a63c9.md b/curriculum/challenges/english/blocks/workshop-string-inspector/68e6172875008fea742a63c9.md
new file mode 100644
index 00000000000..6ed721b41f3
--- /dev/null
+++ b/curriculum/challenges/english/blocks/workshop-string-inspector/68e6172875008fea742a63c9.md
@@ -0,0 +1,60 @@
+---
+id: 68e6172875008fea742a63c9
+title: Step 3
+challengeType: 1
+dashedName: step-3
+---
+
+# --description--
+
+As you recall from the prior lessons, the `includes()` method checks if a string contains a specific substring and returns `true` or `false`.
+
+Here is an example using the `includes()` method:
+
+```js
+const text = "Hello World";
+const hasHello = text.includes("Hello");
+console.log(hasHello); // true
+```
+
+Create a variable named `hasFreeCodeCamp`. Then assign it the result of using the `includes()` method on `fccSentence` to check if it contains `"freeCodeCamp"`.
+
+# --hints--
+
+You should declare a variable named `hasFreeCodeCamp`.
+
+```js
+assert.exists(hasFreeCodeCamp);
+```
+
+You should use `fccSentence.includes("freeCodeCamp")`.
+
+```js
+assert.match(__helpers.removeJSComments(code), /fccSentence\.includes\(\s*(['"`])freeCodeCamp\1\s*\)/);
+```
+
+You should assign the result of `fccSentence.includes("freeCodeCamp")` to your `hasFreeCodeCamp` variable.
+
+```js
+assert.match(__helpers.removeJSComments(code), /hasFreeCodeCamp\s*=\s*fccSentence\.includes\(\s*(['"`])freeCodeCamp\1\s*\)/);
+```
+
+The result of `fccSentence.includes("freeCodeCamp")` should be `true`.
+
+```js
+assert.isTrue(hasFreeCodeCamp);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```js
+const fccSentence = "freeCodeCamp is a great place to learn web development.";
+
+console.log("Here are some examples of the includes() method:");
+
+--fcc-editable-region--
+
+--fcc-editable-region--
+```
diff --git a/curriculum/challenges/english/blocks/workshop-string-inspector/68e6172975008fea742a63ca.md b/curriculum/challenges/english/blocks/workshop-string-inspector/68e6172975008fea742a63ca.md
new file mode 100644
index 00000000000..45eb6a83327
--- /dev/null
+++ b/curriculum/challenges/english/blocks/workshop-string-inspector/68e6172975008fea742a63ca.md
@@ -0,0 +1,39 @@
+---
+id: 68e6172975008fea742a63ca
+title: Step 4
+challengeType: 1
+dashedName: step-4
+---
+
+# --description--
+
+Now use either a template literal or string concatenation to log the message `fccSentence.includes("freeCodeCamp") returns because the word "freeCodeCamp" is in the sentence.` to the console. Replace `` with the actual value of the variable.
+
+# --before-each--
+
+```js
+const spy = __helpers.spyOn(console, 'log');
+```
+
+# --hints--
+
+You should log the message `fccSentence.includes("freeCodeCamp") returns because the word "freeCodeCamp" is in the sentence.`, where `` should be replaced with the actual value of the variable.
+
+```js
+assert.deepInclude(spy.calls, ['fccSentence.includes("freeCodeCamp") returns true because the word "freeCodeCamp" is in the sentence.']);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```js
+const fccSentence = "freeCodeCamp is a great place to learn web development.";
+
+console.log("Here are some examples of the includes() method:");
+
+const hasFreeCodeCamp = fccSentence.includes("freeCodeCamp");
+--fcc-editable-region--
+
+--fcc-editable-region--
+```
diff --git a/curriculum/challenges/english/blocks/workshop-string-inspector/68e6172975008fea742a63cb.md b/curriculum/challenges/english/blocks/workshop-string-inspector/68e6172975008fea742a63cb.md
new file mode 100644
index 00000000000..5b21bd17dc4
--- /dev/null
+++ b/curriculum/challenges/english/blocks/workshop-string-inspector/68e6172975008fea742a63cb.md
@@ -0,0 +1,69 @@
+---
+id: 68e6172975008fea742a63cb
+title: Step 5
+challengeType: 1
+dashedName: step-5
+---
+
+# --description--
+
+Now it is time to see what happens when the substring is NOT found.
+
+Create a variable named `hasJavaScript`. Then assign it the result of using the `includes()` method to check if `fccSentence` includes `"JavaScript"`.
+
+Then use either a template literal or string concatenation to log the message `fccSentence.includes("JavaScript") returns because the word "JavaScript" is not in the sentence.` to the console. Replace `` with the actual value of the variable.
+
+# --before-each--
+
+```js
+const spy = __helpers.spyOn(console, 'log');
+```
+
+# --hints--
+
+You should declare a variable named `hasJavaScript`.
+
+```js
+assert.exists(hasJavaScript);
+```
+
+You should use `fccSentence.includes("JavaScript")`.
+
+```js
+assert.match(__helpers.removeJSComments(code), /fccSentence\.includes\(\s*(['"`])JavaScript\1\s*\)/);
+```
+
+You should assign the result of `fccSentence.includes("JavaScript")` to your `hasJavaScript` variable.
+
+```js
+assert.match(__helpers.removeJSComments(code), /hasJavaScript\s*=\s*fccSentence\.includes\(\s*(['"`])JavaScript\1\s*\)/);
+```
+
+The result of `fccSentence.includes("JavaScript")` should be `false`.
+
+```js
+assert.isFalse(hasJavaScript);
+```
+
+You should log the message `fccSentence.includes("JavaScript") returns because the word "JavaScript" is not in the sentence.`, where `` should be replaced with the actual value of the variable.
+
+```js
+assert.deepInclude(spy.calls, ['fccSentence.includes("JavaScript") returns false because the word "JavaScript" is not in the sentence.']);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```js
+const fccSentence = "freeCodeCamp is a great place to learn web development.";
+
+console.log("Here are some examples of the includes() method:");
+
+const hasFreeCodeCamp = fccSentence.includes("freeCodeCamp");
+console.log(`fccSentence.includes("freeCodeCamp") returns ${hasFreeCodeCamp} because the word "freeCodeCamp" is in the sentence.`);
+
+--fcc-editable-region--
+
+--fcc-editable-region--
+```
diff --git a/curriculum/challenges/english/blocks/workshop-string-inspector/68e6172975008fea742a63cc.md b/curriculum/challenges/english/blocks/workshop-string-inspector/68e6172975008fea742a63cc.md
new file mode 100644
index 00000000000..5e8982a7918
--- /dev/null
+++ b/curriculum/challenges/english/blocks/workshop-string-inspector/68e6172975008fea742a63cc.md
@@ -0,0 +1,72 @@
+---
+id: 68e6172975008fea742a63cc
+title: Step 6
+challengeType: 1
+dashedName: step-6
+---
+
+# --description--
+
+The `includes()` method is case-sensitive, meaning it distinguishes between uppercase and lowercase letters.
+
+Create a variable named `hasLowercaseFCC`. Then assign it the result of using the `includes()` method to check if `fccSentence` includes `"freecodecamp"` (all lowercase).
+
+Then use either a template literal or string concatenation to log the message `fccSentence.includes("freecodecamp") returns because includes is case-sensitive.` to the console. Replace `` with the actual value of the variable.
+
+# --before-each--
+
+```js
+const spy = __helpers.spyOn(console, 'log');
+```
+
+# --hints--
+
+You should declare a variable named `hasLowercaseFCC`.
+
+```js
+assert.exists(hasLowercaseFCC);
+```
+
+You should use `fccSentence.includes("freecodecamp")`.
+
+```js
+assert.match(__helpers.removeJSComments(code), /fccSentence\.includes\(\s*(['"`])freecodecamp\1\s*\)/);
+```
+
+You should assign the result of `fccSentence.includes("freecodecamp")` to your `hasLowercaseFCC` variable.
+
+```js
+assert.match(__helpers.removeJSComments(code), /hasLowercaseFCC\s*=\s*fccSentence\.includes\(\s*(['"`])freecodecamp\1\s*\)/);
+```
+
+The result of `fccSentence.includes("freecodecamp")` should be `false`.
+
+```js
+assert.isFalse(hasLowercaseFCC);
+```
+
+You should log the message that includes `fccSentence.includes("freecodecamp") returns because includes is case-sensitive.`, where `` should be replaced with the actual value of the variable.
+
+```js
+assert.deepInclude(spy.calls, ['fccSentence.includes("freecodecamp") returns false because includes is case-sensitive.']);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```js
+const fccSentence = "freeCodeCamp is a great place to learn web development.";
+
+console.log("Here are some examples of the includes() method:");
+
+const hasFreeCodeCamp = fccSentence.includes("freeCodeCamp");
+console.log(`fccSentence.includes("freeCodeCamp") returns ${hasFreeCodeCamp} because the word "freeCodeCamp" is in the sentence.`);
+
+const hasJavaScript = fccSentence.includes("JavaScript");
+console.log(`fccSentence.includes("JavaScript") returns ${hasJavaScript} because the word "JavaScript" is not in the sentence.`);
+
+--fcc-editable-region--
+
+--fcc-editable-region--
+```
diff --git a/curriculum/challenges/english/blocks/workshop-string-inspector/68e6172975008fea742a63cd.md b/curriculum/challenges/english/blocks/workshop-string-inspector/68e6172975008fea742a63cd.md
new file mode 100644
index 00000000000..6356268586e
--- /dev/null
+++ b/curriculum/challenges/english/blocks/workshop-string-inspector/68e6172975008fea742a63cd.md
@@ -0,0 +1,63 @@
+---
+id: 68e6172975008fea742a63cd
+title: Step 7
+challengeType: 1
+dashedName: step-7
+---
+
+# --description--
+
+Now you will explore the `slice()` method, which extracts a portion of a string.
+
+Create a variable named `message` and assign it the string `"Welcome to freeCodeCamp!"`.
+
+Then use `console.log()` to log `"Here are some examples of the slice() method:"` to the console.
+
+# --hints--
+
+You should declare a variable named `message`.
+
+```js
+assert.exists(message);
+```
+
+Your `message` variable should be a string.
+
+```js
+assert.isString(message);
+```
+
+Your `message` variable should be `"Welcome to freeCodeCamp!"`.
+
+```js
+assert.strictEqual(message, "Welcome to freeCodeCamp!");
+```
+
+You should log `"Here are some examples of the slice() method:"` to the console.
+
+```js
+assert.match(__helpers.removeJSComments(code), /console\.log\s*\(\s*('|"|`)Here are some examples of the slice\(\) method:\1\s*\)/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```js
+const fccSentence = "freeCodeCamp is a great place to learn web development.";
+
+console.log("Here are some examples of the includes() method:");
+
+const hasFreeCodeCamp = fccSentence.includes("freeCodeCamp");
+console.log(`fccSentence.includes("freeCodeCamp") returns ${hasFreeCodeCamp} because the word "freeCodeCamp" is in the sentence.`);
+
+const hasJavaScript = fccSentence.includes("JavaScript");
+console.log(`fccSentence.includes("JavaScript") returns ${hasJavaScript} because the word "JavaScript" is not in the sentence.`);
+
+const hasLowercaseFCC = fccSentence.includes("freecodecamp");
+console.log(`fccSentence.includes("freecodecamp") returns ${hasLowercaseFCC} because includes is case-sensitive.`);
+
+--fcc-editable-region--
+
+--fcc-editable-region--
+```
diff --git a/curriculum/challenges/english/blocks/workshop-string-inspector/68e6172975008fea742a63ce.md b/curriculum/challenges/english/blocks/workshop-string-inspector/68e6172975008fea742a63ce.md
new file mode 100644
index 00000000000..7334740f8d9
--- /dev/null
+++ b/curriculum/challenges/english/blocks/workshop-string-inspector/68e6172975008fea742a63ce.md
@@ -0,0 +1,81 @@
+---
+id: 68e6172975008fea742a63ce
+title: Step 8
+challengeType: 1
+dashedName: step-8
+---
+
+# --description--
+
+The `slice()` method extracts a section of a string. It takes two arguments: the start index (included) and the end index (not included).
+
+Here is an example:
+
+```js
+const greeting = "Hello World";
+const firstWord = greeting.slice(0, 5);
+console.log(firstWord); // "Hello"
+```
+
+String indices start at 0. In the `message` string, the character at index 11 is `f` (the start of "freeCodeCamp").
+
+Create a variable named `platform`. Then assign it the result of using `message.slice(11, 23)` to extract `"freeCodeCamp"`.
+
+# --hints--
+
+You should declare a variable named `platform`.
+
+```js
+assert.exists(platform);
+```
+
+Your `platform` variable should be a string.
+
+```js
+assert.isString(platform);
+```
+
+You should use `message.slice(11, 23)`.
+
+```js
+assert.match(__helpers.removeJSComments(code), /message\.slice\(\s*11\s*,\s*23\s*\)/);
+```
+
+You should assign the result of `message.slice(11, 23)` to your `platform` variable.
+
+```js
+assert.match(__helpers.removeJSComments(code), /platform\s*=\s*message\.slice\(\s*11\s*,\s*23\s*\)/);
+```
+
+Your `platform` variable should equal `"freeCodeCamp"`.
+
+```js
+assert.strictEqual(platform, "freeCodeCamp");
+```
+
+# --seed--
+
+## --seed-contents--
+
+```js
+const fccSentence = "freeCodeCamp is a great place to learn web development.";
+
+console.log("Here are some examples of the includes() method:");
+
+const hasFreeCodeCamp = fccSentence.includes("freeCodeCamp");
+console.log(`fccSentence.includes("freeCodeCamp") returns ${hasFreeCodeCamp} because the word "freeCodeCamp" is in the sentence.`);
+
+const hasJavaScript = fccSentence.includes("JavaScript");
+console.log(`fccSentence.includes("JavaScript") returns ${hasJavaScript} because the word "JavaScript" is not in the sentence.`);
+
+const hasLowercaseFCC = fccSentence.includes("freecodecamp");
+console.log(`fccSentence.includes("freecodecamp") returns ${hasLowercaseFCC} because includes is case-sensitive.`);
+
+const message = "Welcome to freeCodeCamp!";
+
+console.log("Here are some examples of the slice() method:");
+
+--fcc-editable-region--
+
+--fcc-editable-region--
+```
diff --git a/curriculum/challenges/english/blocks/workshop-string-inspector/68e6172975008fea742a63cf.md b/curriculum/challenges/english/blocks/workshop-string-inspector/68e6172975008fea742a63cf.md
new file mode 100644
index 00000000000..c4686a3d939
--- /dev/null
+++ b/curriculum/challenges/english/blocks/workshop-string-inspector/68e6172975008fea742a63cf.md
@@ -0,0 +1,54 @@
+---
+id: 68e6172975008fea742a63cf
+title: Step 9
+challengeType: 1
+dashedName: step-9
+---
+
+# --description--
+
+Now it is time to log the result of using the `slice()` method.
+
+Use either a template literal or string concatenation to log the message `The word "" was sliced from the message.` to the console. Replace `` with the actual value of the variable.
+
+# --before-each--
+
+```js
+const spy = __helpers.spyOn(console, 'log');
+```
+
+# --hints--
+
+You should log the message `The word "" was sliced from the message.`, where `` should be replaced with the actual value of the variable.
+
+```js
+assert.deepInclude(spy.calls, ['The word "freeCodeCamp" was sliced from the message.']);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```js
+const fccSentence = "freeCodeCamp is a great place to learn web development.";
+
+console.log("Here are some examples of the includes() method:");
+
+const hasFreeCodeCamp = fccSentence.includes("freeCodeCamp");
+console.log(`fccSentence.includes("freeCodeCamp") returns ${hasFreeCodeCamp} because the word "freeCodeCamp" is in the sentence.`);
+
+const hasJavaScript = fccSentence.includes("JavaScript");
+console.log(`fccSentence.includes("JavaScript") returns ${hasJavaScript} because the word "JavaScript" is not in the sentence.`);
+
+const hasLowercaseFCC = fccSentence.includes("freecodecamp");
+console.log(`fccSentence.includes("freecodecamp") returns ${hasLowercaseFCC} because includes is case-sensitive.`);
+
+const message = "Welcome to freeCodeCamp!";
+
+console.log("Here are some examples of the slice() method:");
+
+const platform = message.slice(11, 23);
+--fcc-editable-region--
+
+--fcc-editable-region--
+```
diff --git a/curriculum/challenges/english/blocks/workshop-string-inspector/68e6172975008fea742a63d0.md b/curriculum/challenges/english/blocks/workshop-string-inspector/68e6172975008fea742a63d0.md
new file mode 100644
index 00000000000..10c372f5148
--- /dev/null
+++ b/curriculum/challenges/english/blocks/workshop-string-inspector/68e6172975008fea742a63d0.md
@@ -0,0 +1,88 @@
+---
+id: 68e6172975008fea742a63d0
+title: Step 10
+challengeType: 1
+dashedName: step-10
+---
+
+# --description--
+
+You can use `slice()` to extract from the beginning of a string.
+
+Create a variable named `greetingWord`. Then assign it the result of using `message.slice(0, 7)` to extract the first word `"Welcome"`.
+
+Then use either a template literal or string concatenation to log the message `The first word is "".` to the console. Replace `` with the actual value of the variable.
+
+# --before-each--
+
+```js
+const spy = __helpers.spyOn(console, 'log');
+```
+
+# --hints--
+
+You should declare a variable named `greetingWord`.
+
+```js
+assert.exists(greetingWord);
+```
+
+Your `greetingWord` variable should be a string.
+
+```js
+assert.isString(greetingWord);
+```
+
+You should use `message.slice(0, 7)`.
+
+```js
+assert.match(__helpers.removeJSComments(code), /message\.slice\(\s*0\s*,\s*7\s*\)/);
+```
+
+You should assign the result of `message.slice(0, 7)` to your `greetingWord` variable.
+
+```js
+assert.match(__helpers.removeJSComments(code), /greetingWord\s*=\s*message\.slice\(\s*0\s*,\s*7\s*\)/);
+```
+
+Your `greetingWord` variable should equal `"Welcome"`.
+
+```js
+assert.strictEqual(greetingWord, "Welcome");
+```
+
+You should log the message `The first word is "".`, where `` should be replaced by the actual value of the variable.
+
+```js
+assert.deepInclude(spy.calls, ['The first word is "Welcome".']);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```js
+const fccSentence = "freeCodeCamp is a great place to learn web development.";
+
+console.log("Here are some examples of the includes() method:");
+
+const hasFreeCodeCamp = fccSentence.includes("freeCodeCamp");
+console.log(`fccSentence.includes("freeCodeCamp") returns ${hasFreeCodeCamp} because the word "freeCodeCamp" is in the sentence.`);
+
+const hasJavaScript = fccSentence.includes("JavaScript");
+console.log(`fccSentence.includes("JavaScript") returns ${hasJavaScript} because the word "JavaScript" is not in the sentence.`);
+
+const hasLowercaseFCC = fccSentence.includes("freecodecamp");
+console.log(`fccSentence.includes("freecodecamp") returns ${hasLowercaseFCC} because includes is case-sensitive.`);
+
+const message = "Welcome to freeCodeCamp!";
+
+console.log("Here are some examples of the slice() method:");
+
+const platform = message.slice(11, 23);
+console.log(`The word "${platform}" was sliced from the message.`);
+
+--fcc-editable-region--
+
+--fcc-editable-region--
+```
diff --git a/curriculum/challenges/english/blocks/workshop-string-inspector/68e6172975008fea742a63d1.md b/curriculum/challenges/english/blocks/workshop-string-inspector/68e6172975008fea742a63d1.md
new file mode 100644
index 00000000000..b032236d509
--- /dev/null
+++ b/curriculum/challenges/english/blocks/workshop-string-inspector/68e6172975008fea742a63d1.md
@@ -0,0 +1,99 @@
+---
+id: 68e6172975008fea742a63d1
+title: Step 11
+challengeType: 1
+dashedName: step-11
+---
+
+# --description--
+
+The `slice()` method can use negative indices to count from the end of the string. `-1` refers to the last character.
+
+Here is an example:
+
+```js
+const text = "JavaScript";
+const lastThree = text.slice(-3);
+console.log(lastThree); // "ipt"
+```
+
+Create a variable named `endPunctuation`. Then assign it the result of using `message.slice(-1)` to extract the last character.
+
+Then use either a template literal or string concatenation to log the message `The ending punctuation mark is a ""` to the console. Replace `` with the actual value of the variable.
+
+# --before-each--
+
+```js
+const spy = __helpers.spyOn(console, 'log');
+```
+
+# --hints--
+
+You should declare a variable named `endPunctuation`.
+
+```js
+assert.exists(endPunctuation);
+```
+
+Your `endPunctuation` variable should be a string.
+
+```js
+assert.isString(endPunctuation);
+```
+
+You should use `message.slice(-1)`.
+
+```js
+assert.match(__helpers.removeJSComments(code), /message\.slice\(\s*-1\s*\)/);
+```
+
+You should assign the result of `message.slice(-1)` to your `endPunctuation` variable.
+
+```js
+assert.match(__helpers.removeJSComments(code), /endPunctuation\s*=\s*message\.slice\(\s*-1\s*\)/);
+```
+
+Your `endPunctuation` variable should equal `"!"`.
+
+```js
+assert.strictEqual(endPunctuation, "!");
+```
+
+You should log the message `The ending punctuation mark is a ""`, where `` should be replaced with the actual value of the variable.
+
+```js
+assert.deepInclude(spy.calls, ['The ending punctuation mark is a "!"']);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```js
+const fccSentence = "freeCodeCamp is a great place to learn web development.";
+
+console.log("Here are some examples of the includes() method:");
+
+const hasFreeCodeCamp = fccSentence.includes("freeCodeCamp");
+console.log(`fccSentence.includes("freeCodeCamp") returns ${hasFreeCodeCamp} because the word "freeCodeCamp" is in the sentence.`);
+
+const hasJavaScript = fccSentence.includes("JavaScript");
+console.log(`fccSentence.includes("JavaScript") returns ${hasJavaScript} because the word "JavaScript" is not in the sentence.`);
+
+const hasLowercaseFCC = fccSentence.includes("freecodecamp");
+console.log(`fccSentence.includes("freecodecamp") returns ${hasLowercaseFCC} because includes is case-sensitive.`);
+
+const message = "Welcome to freeCodeCamp!";
+
+console.log("Here are some examples of the slice() method:");
+
+const platform = message.slice(11, 23);
+console.log(`The word "${platform}" was sliced from the message.`);
+
+const greetingWord = message.slice(0, 7);
+console.log(`The first word is "${greetingWord}".`);
+
+--fcc-editable-region--
+
+--fcc-editable-region--
+```
diff --git a/curriculum/challenges/english/blocks/workshop-string-inspector/68e6172975008fea742a63d2.md b/curriculum/challenges/english/blocks/workshop-string-inspector/68e6172975008fea742a63d2.md
new file mode 100644
index 00000000000..2e0883ed101
--- /dev/null
+++ b/curriculum/challenges/english/blocks/workshop-string-inspector/68e6172975008fea742a63d2.md
@@ -0,0 +1,88 @@
+---
+id: 68e6172975008fea742a63d2
+title: Step 12
+challengeType: 1
+dashedName: step-12
+---
+
+# --description--
+
+As a final step, add a `console.log()` statement with the message: `"Workshop complete! You now know how to use includes() and slice()."`
+
+Congratulations! You have completed the String Inspector workshop.
+
+# --hints--
+
+You should log `"Workshop complete! You now know how to use includes() and slice()."` to the console.
+
+```js
+assert.match(__helpers.removeJSComments(code), /console\.log\s*\(\s*('|"|`)Workshop complete! You now know how to use includes\(\) and slice\(\)\.\1\s*\)/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```js
+const fccSentence = "freeCodeCamp is a great place to learn web development.";
+
+console.log("Here are some examples of the includes() method:");
+
+const hasFreeCodeCamp = fccSentence.includes("freeCodeCamp");
+console.log(`fccSentence.includes("freeCodeCamp") returns ${hasFreeCodeCamp} because the word "freeCodeCamp" is in the sentence.`);
+
+const hasJavaScript = fccSentence.includes("JavaScript");
+console.log(`fccSentence.includes("JavaScript") returns ${hasJavaScript} because the word "JavaScript" is not in the sentence.`);
+
+const hasLowercaseFCC = fccSentence.includes("freecodecamp");
+console.log(`fccSentence.includes("freecodecamp") returns ${hasLowercaseFCC} because includes is case-sensitive.`);
+
+const message = "Welcome to freeCodeCamp!";
+
+console.log("Here are some examples of the slice() method:");
+
+const platform = message.slice(11, 23);
+console.log(`The word "${platform}" was sliced from the message.`);
+
+const greetingWord = message.slice(0, 7);
+console.log(`The first word is "${greetingWord}".`);
+
+const endPunctuation = message.slice(-1);
+console.log(`The ending punctuation mark is a "${endPunctuation}"`);
+
+--fcc-editable-region--
+
+--fcc-editable-region--
+```
+
+# --solutions--
+
+```js
+const fccSentence = "freeCodeCamp is a great place to learn web development.";
+
+console.log("Here are some examples of the includes() method:");
+
+const hasFreeCodeCamp = fccSentence.includes("freeCodeCamp");
+console.log(`fccSentence.includes("freeCodeCamp") returns ${hasFreeCodeCamp} because the word "freeCodeCamp" is in the sentence.`);
+
+const hasJavaScript = fccSentence.includes("JavaScript");
+console.log(`fccSentence.includes("JavaScript") returns ${hasJavaScript} because the word "JavaScript" is not in the sentence.`);
+
+const hasLowercaseFCC = fccSentence.includes("freecodecamp");
+console.log(`fccSentence.includes("freecodecamp") returns ${hasLowercaseFCC} because includes is case-sensitive.`);
+
+const message = "Welcome to freeCodeCamp!";
+
+console.log("Here are some examples of the slice() method:");
+
+const platform = message.slice(11, 23);
+console.log(`The word "${platform}" was sliced from the message.`);
+
+const greetingWord = message.slice(0, 7);
+console.log(`The first word is "${greetingWord}".`);
+
+const endPunctuation = message.slice(-1);
+console.log(`The ending punctuation mark is a "${endPunctuation}"`);
+
+console.log("Workshop complete! You now know how to use includes() and slice().");
+```
diff --git a/curriculum/challenges/english/blocks/workshop-string-inspector/68ef6e42fa6e8a9a18a401fa.md b/curriculum/challenges/english/blocks/workshop-string-inspector/68ef6e42fa6e8a9a18a401fa.md
new file mode 100644
index 00000000000..4fd77664420
--- /dev/null
+++ b/curriculum/challenges/english/blocks/workshop-string-inspector/68ef6e42fa6e8a9a18a401fa.md
@@ -0,0 +1,36 @@
+---
+id: 68ef6e42fa6e8a9a18a401fa
+title: Step 2
+challengeType: 1
+dashedName: step-2
+---
+
+# --description--
+
+Use `console.log()` to log `"Here are some examples of the includes() method:"` to the console.
+
+# --before-each--
+
+```js
+const spy = __helpers.spyOn(console, 'log');
+```
+
+# --hints--
+
+You should log `"Here are some examples of the includes() method:"` to the console.
+
+```js
+assert.deepInclude(spy.calls, ["Here are some examples of the includes() method:"])
+```
+
+# --seed--
+
+## --seed-contents--
+
+```js
+const fccSentence = "freeCodeCamp is a great place to learn web development.";
+
+--fcc-editable-region--
+
+--fcc-editable-region--
+```
diff --git a/curriculum/structure/blocks/workshop-string-inspector.json b/curriculum/structure/blocks/workshop-string-inspector.json
new file mode 100644
index 00000000000..5942f392b4d
--- /dev/null
+++ b/curriculum/structure/blocks/workshop-string-inspector.json
@@ -0,0 +1,24 @@
+{
+ "name": "Build a String Inspector",
+ "isUpcomingChange": true,
+ "dashedName": "workshop-string-inspector",
+ "helpCategory": "JavaScript",
+ "blockLayout": "challenge-grid",
+ "challengeOrder": [
+ { "id": "68e51d8f163d3f8b70f9c4e5", "title": "Step 1" },
+ { "id": "68ef6e42fa6e8a9a18a401fa", "title": "Step 2" },
+ { "id": "68e6172875008fea742a63c9", "title": "Step 3" },
+ { "id": "68e6172975008fea742a63ca", "title": "Step 4" },
+ { "id": "68e6172975008fea742a63cb", "title": "Step 5" },
+ { "id": "68e6172975008fea742a63cc", "title": "Step 6" },
+ { "id": "68e6172975008fea742a63cd", "title": "Step 7" },
+ { "id": "68e6172975008fea742a63ce", "title": "Step 8" },
+ { "id": "68e6172975008fea742a63cf", "title": "Step 9" },
+ { "id": "68e6172975008fea742a63d0", "title": "Step 10" },
+ { "id": "68e6172975008fea742a63d1", "title": "Step 11" },
+ { "id": "68e6172975008fea742a63d2", "title": "Step 12" }
+ ],
+ "blockLabel": "workshop",
+ "usesMultifileEditor": true,
+ "hasEditableBoundaries": true
+}
diff --git a/curriculum/structure/superblocks/full-stack-developer.json b/curriculum/structure/superblocks/full-stack-developer.json
index 9f6f7e5cd1e..1daa5634c15 100644
--- a/curriculum/structure/superblocks/full-stack-developer.json
+++ b/curriculum/structure/superblocks/full-stack-developer.json
@@ -293,6 +293,7 @@
"workshop-teacher-chatbot",
"lecture-working-with-string-character-methods",
"lecture-working-with-string-search-and-slice-methods",
+ "workshop-string-inspector",
"lecture-working-with-string-formatting-methods",
"lecture-working-with-string-modification-methods",
"workshop-string-transformer",