diff --git a/apps/sodo-search/src/App.js b/apps/sodo-search/src/App.js
index f67ba9f80d..e4db34bd86 100644
--- a/apps/sodo-search/src/App.js
+++ b/apps/sodo-search/src/App.js
@@ -3,6 +3,7 @@ import './App.css';
import AppContext from './AppContext';
import PopupModal from './components/PopupModal';
import SearchIndex from './search-index.js';
+import i18nLib from '@tryghost/i18n';
export default class App extends React.Component {
constructor(props) {
@@ -13,11 +14,15 @@ export default class App extends React.Component {
apiKey: props.apiKey
});
+ const i18nLanguage = this.props.locale || 'en';
+ const i18n = i18nLib(i18nLanguage, 'search');
+
this.state = {
searchIndex,
showPopup: false,
indexStarted: false,
- indexComplete: false
+ indexComplete: false,
+ t: i18n.t
};
this.inputRef = React.createRef();
@@ -163,7 +168,8 @@ export default class App extends React.Component {
...data
});
}
- }
+ },
+ t: this.state.t
}}>
diff --git a/apps/sodo-search/src/AppContext.js b/apps/sodo-search/src/AppContext.js
index e8648eaa9f..420758711d 100644
--- a/apps/sodo-search/src/AppContext.js
+++ b/apps/sodo-search/src/AppContext.js
@@ -13,7 +13,8 @@ const AppContext = React.createContext({
dispatch: (_action, _data) => {},
searchIndex: null,
indexComplete: false,
- searchValue: ''
+ searchValue: '',
+ t: () => {}
});
export default AppContext;
diff --git a/apps/sodo-search/src/components/PopupModal.js b/apps/sodo-search/src/components/PopupModal.js
index 443cd14479..832420e881 100644
--- a/apps/sodo-search/src/components/PopupModal.js
+++ b/apps/sodo-search/src/components/PopupModal.js
@@ -71,7 +71,7 @@ class PopupContent extends React.Component {
}
function SearchBox() {
- const {searchValue, dispatch, inputRef} = useContext(AppContext);
+ const {searchValue, dispatch, inputRef, t} = useContext(AppContext);
const containerRef = useRef(null);
useEffect(() => {
setTimeout(() => {
@@ -117,7 +117,7 @@ function SearchBox() {
}
}}
className='grow -my-5 py-5 -ml-3 pl-3 text-[1.65rem] focus-visible:outline-none placeholder:text-gray-400 outline-none truncate'
- placeholder='Search posts, tags and authors'
+ placeholder={t('Search posts, tags and authors')}
/>
@@ -154,7 +154,7 @@ function Loading() {
}
function CancelButton() {
- const {dispatch} = useContext(AppContext);
+ const {dispatch, t} = useContext(AppContext);
return (
);
}
@@ -195,6 +195,8 @@ function TagListItem({tag, selectedResult, setSelectedResult}) {
}
function TagResults({tags, selectedResult, setSelectedResult}) {
+ const {t} = useContext(AppContext);
+
if (!tags?.length) {
return null;
}
@@ -210,7 +212,7 @@ function TagResults({tags, selectedResult, setSelectedResult}) {
});
return (
-
Tags
+ {t('Tags')}
{TagItems}
);
@@ -355,6 +357,8 @@ function HighlightWord({word, isExcerpt}) {
}
function ShowMoreButton({posts, maxPosts, setMaxPosts}) {
+ const {t} = useContext(AppContext);
+
if (!posts?.length || maxPosts >= posts?.length) {
return null;
}
@@ -366,12 +370,13 @@ function ShowMoreButton({posts, maxPosts, setMaxPosts}) {
setMaxPosts(updatedMaxPosts);
}}
>
- Show more results
+ {t('Show more results')}
);
}
function PostResults({posts, selectedResult, setSelectedResult}) {
+ const {t} = useContext(AppContext);
const [maxPosts, setMaxPosts] = useState(DEFAULT_MAX_POSTS);
useEffect(() => {
setMaxPosts(DEFAULT_MAX_POSTS);
@@ -392,7 +397,7 @@ function PostResults({posts, selectedResult, setSelectedResult}) {
});
return (
-
Posts
+ {t('Posts')}
{PostItems}
@@ -437,6 +442,8 @@ function AuthorAvatar({name, avatar}) {
}
function AuthorResults({authors, selectedResult, setSelectedResult}) {
+ const {t} = useContext(AppContext);
+
if (!authors?.length) {
return null;
}
@@ -453,7 +460,7 @@ function AuthorResults({authors, selectedResult, setSelectedResult}) {
return (
-
Authors
+ {t('Authors')}
{AuthorItems}
);
@@ -572,9 +579,10 @@ function Results({posts, authors, tags}) {
}
function NoResultsBox() {
+ const {t} = useContext(AppContext);
return (
-
No matches found
+
{t('No matches found')}
);
}
diff --git a/apps/sodo-search/src/index.js b/apps/sodo-search/src/index.js
index fa5627c15b..f5e9fff733 100644
--- a/apps/sodo-search/src/index.js
+++ b/apps/sodo-search/src/index.js
@@ -20,7 +20,8 @@ function getSiteData() {
const adminUrl = scriptTag.dataset.sodoSearch;
const apiKey = scriptTag.dataset.key;
const stylesUrl = scriptTag.dataset.styles;
- return {adminUrl, apiKey, stylesUrl};
+ const locale = scriptTag.dataset.locale || 'en';
+ return {adminUrl, apiKey, stylesUrl, locale};
}
return {};
}
@@ -30,14 +31,14 @@ function setup() {
}
function init() {
- const {adminUrl, apiKey, stylesUrl} = getSiteData();
+ const {adminUrl, apiKey, stylesUrl, locale} = getSiteData();
const adminBaseUrl = (adminUrl || window.location.origin)?.replace(/\/+$/, '');
setup();
ReactDOM.render(
,
document.getElementById(ROOT_DIV_ID)
diff --git a/ghost/core/core/frontend/helpers/ghost_head.js b/ghost/core/core/frontend/helpers/ghost_head.js
index c8ffc9158b..cd2e3f2664 100644
--- a/ghost/core/core/frontend/helpers/ghost_head.js
+++ b/ghost/core/core/frontend/helpers/ghost_head.js
@@ -86,7 +86,8 @@ function getSearchHelper(frontendKey) {
const attrs = {
key: frontendKey,
styles: stylesUrl,
- 'sodo-search': adminUrl
+ 'sodo-search': adminUrl,
+ locale: settingsCache.get('locale') || 'en'
};
const dataAttrs = getDataAttributes(attrs);
let helper = ``;
diff --git a/ghost/core/test/unit/frontend/helpers/__snapshots__/ghost_head.test.js.snap b/ghost/core/test/unit/frontend/helpers/__snapshots__/ghost_head.test.js.snap
index b9bd03697e..fe165a6472 100644
--- a/ghost/core/test/unit/frontend/helpers/__snapshots__/ghost_head.test.js.snap
+++ b/ghost/core/test/unit/frontend/helpers/__snapshots__/ghost_head.test.js.snap
@@ -131,7 +131,7 @@ Object {
.gh-post-upgrade-cta a.gh-btn:hover {
opacity: 0.92;
}
-
+
",
@@ -275,7 +275,7 @@ Object {
-
+
",
}
@@ -286,7 +286,7 @@ Object {
"rendered": "
-
+
@@ -299,7 +299,7 @@ Object {
"rendered": "
-
+
",
}
@@ -373,7 +373,7 @@ Object {
-
+
",
}
@@ -446,7 +446,7 @@ Object {
-
+
",
}
@@ -839,7 +839,7 @@ Object {
.gh-post-upgrade-cta a.gh-btn:hover {
opacity: 0.92;
}
-
+
",
@@ -953,7 +953,7 @@ Object {
.gh-post-upgrade-cta a.gh-btn:hover {
opacity: 0.92;
}
-
+
",
}
@@ -1022,7 +1022,7 @@ Object {
-
+
",
@@ -1092,7 +1092,7 @@ Object {
-
+
",
@@ -1143,7 +1143,7 @@ Object {
-
+
",
@@ -1194,7 +1194,7 @@ Object {
-
+
",
@@ -1308,7 +1308,7 @@ Object {
.gh-post-upgrade-cta a.gh-btn:hover {
opacity: 0.92;
}
-
+
",
@@ -1422,7 +1422,7 @@ Object {
.gh-post-upgrade-cta a.gh-btn:hover {
opacity: 0.92;
}
-
+
",
@@ -1473,7 +1473,7 @@ Object {
-
+
",
}
@@ -1586,7 +1586,7 @@ Object {
.gh-post-upgrade-cta a.gh-btn:hover {
opacity: 0.92;
}
-
+
",
@@ -1637,7 +1637,7 @@ Object {
-
+
",
}
@@ -1651,7 +1651,7 @@ Object {
-
+
",
}
@@ -1665,7 +1665,7 @@ Object {
-
+
",
@@ -1680,7 +1680,7 @@ Object {
-
+
",
@@ -1695,7 +1695,7 @@ Object {
-
+
@@ -1711,7 +1711,7 @@ Object {
-
+
",
@@ -1796,7 +1796,7 @@ Object {
-
+
",
}
@@ -1812,7 +1812,7 @@ Object {
-
+
",
}
@@ -1838,7 +1838,7 @@ Object {
-
+
",
}
@@ -1888,7 +1888,7 @@ Object {
-
+
",
}
@@ -1901,7 +1901,7 @@ Object {
-
+
",
}
@@ -1914,7 +1914,7 @@ Object {
-
+
",
}
@@ -1974,7 +1974,7 @@ Object {
-
+
",
@@ -2025,7 +2025,7 @@ Object {
-
+
",
@@ -2048,7 +2048,7 @@ Object {
-
+
",
}
@@ -2113,7 +2113,7 @@ Object {
-
+
",
}
@@ -2163,7 +2163,7 @@ Object {
-
+
",
}
@@ -2185,7 +2185,7 @@ Object {
-
+
",
}
@@ -2198,7 +2198,7 @@ Object {
-
+
",
}
@@ -2213,7 +2213,7 @@ Object {
-
+
",
}
@@ -2228,7 +2228,7 @@ Object {
-
+
",
}
@@ -2280,7 +2280,7 @@ Object {
-
+
",
}
@@ -2330,7 +2330,7 @@ Object {
-
+
",
}
@@ -2411,7 +2411,7 @@ Object {
-
+
",
}
@@ -2537,7 +2537,7 @@ Object {
-
+
",
}
@@ -2618,7 +2618,7 @@ Object {
-
+
",
}
@@ -2699,7 +2699,7 @@ Object {
-
+
",
}
@@ -2768,7 +2768,7 @@ Object {
-
+
",
}
@@ -2841,7 +2841,7 @@ Object {
-
+
",
}
@@ -2914,7 +2914,7 @@ Object {
-
+
",
}
@@ -2987,7 +2987,7 @@ Object {
-
+
",
}
@@ -3061,7 +3061,7 @@ Object {
-
+
",
}
@@ -3127,7 +3127,7 @@ Object {
-
+
",
}
@@ -3175,7 +3175,7 @@ Object {
-
+
",
}
@@ -3227,7 +3227,7 @@ Object {
-
+
",
}
diff --git a/ghost/i18n/lib/i18n.js b/ghost/i18n/lib/i18n.js
index 42aa92e685..82bbe3546b 100644
--- a/ghost/i18n/lib/i18n.js
+++ b/ghost/i18n/lib/i18n.js
@@ -49,7 +49,7 @@ const SUPPORTED_LOCALES = [
/**
* @param {string} [lng]
- * @param {'ghost'|'portal'|'test'|'signup-form'|'comments'} ns
+ * @param {'ghost'|'portal'|'test'|'signup-form'|'comments'|'search'} ns
*/
module.exports = (lng = 'en', ns = 'portal') => {
const i18nextInstance = i18next.createInstance();
diff --git a/ghost/i18n/locales/af/search.json b/ghost/i18n/locales/af/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/af/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/bg/search.json b/ghost/i18n/locales/bg/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/bg/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/bs/search.json b/ghost/i18n/locales/bs/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/bs/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/ca/search.json b/ghost/i18n/locales/ca/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/ca/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/context.json b/ghost/i18n/locales/context.json
index 0818dbb720..7084133296 100644
--- a/ghost/i18n/locales/context.json
+++ b/ghost/i18n/locales/context.json
@@ -13,6 +13,7 @@
"Already a member?": "A link displayed on signup screen, inviting people to log in if they have already signed up previously",
"An unexpected error occured. Please try again or contact support if the error persists.": "Notification if an unexpected error occurs.",
"Anonymous": "Comment placed by a member without a name",
+ "Authors": "",
"Back": "A button to return to the previous page",
"Back to Log in": "A button to return to the login screen",
"Become a member of {{publication}} to start commenting.": "A call to action letting people know they need to sign up before commenting",
@@ -118,6 +119,7 @@
"Need more help? Contact support": "A link to contact support",
"Neurosurgeon": "Example of an expertise of a person used in comments when editing your expertise",
"Newsletters can be disabled on your account for two reasons: A previous email was marked as spam, or attempting to send an email resulted in a permanent failure (bounce).": "A paragraph in the email suppression FAQ",
+ "No matches found": "",
"Not receiving emails?": "A link in portal to take members to an FAQ area about what to do if you're not receiving emails",
"Now check your email!": "A confirmation message after logging in or signing up",
"Once resubscribed, if you still don't see emails in your inbox, check your spam folder. Some inbox providers keep a record of previous spam complaints and will continue to flag emails. If this happens, mark the latest newsletter as 'Not spam' to move it back to your primary inbox.": "A paragraph in the email suppression FAQ",
@@ -137,6 +139,7 @@
"Please enter a valid email address": "Err message when an email address is invalid",
"Please enter {{fieldName}}": "Error message when a required field is missing",
"Please fill in required fields": "Error message when a required field is missing",
+ "Posts": "",
"Price": "A label to indicate price of a tier",
"Re-enable emails": "A button for members to turn-back-on emails, if they have been previously disabled as a result of delivery failures",
"Recommendations": "A suggestion by/for another site of interest to users",
@@ -148,6 +151,7 @@
"Report this comment?": "Title of the modal to report a comment",
"Retry": "When something goes wrong, this link allows people to re-attempt the same action",
"Save": "A button to save",
+ "Search posts, tags and authors": "",
"Secure sign in link for {{siteTitle}}": "The subject line of member login emails",
"See you soon!": "A sign-off/ending to a signup email",
"Send an email and say hi!": "A section title in email receiving FAQ",
@@ -162,6 +166,7 @@
"Show 1 previous comment": "Button in comments app to load previous comments, when there is only one",
"Show all": "Show all recommendations",
"Show comment": "Context menu action for a comment, for administrators",
+ "Show more results": "",
"Show {{amount}} more replies": "Button text to load more replies for a comment",
"Show {{amount}} previous comments": "Button in comments appto load previous comments",
"Sign in": "A button to sign in",
@@ -186,6 +191,7 @@
"Success! Your account is fully activated, you now have access to all content.": "Notification text when a user has activated their email and can access content",
"Success! Your email is updated.": "Notification text when a user has updated their email address",
"Successfully unsubscribed": "A confirmation message when a member clicks an unsubscribe link",
+ "Tags": "",
"Tap the link below to complete the signup process for {{siteTitle}}, and be automatically signed in:": "Descriptive text in signup emails, right before the button to confirm signup",
"Thank you for signing up to {{siteTitle}}!": "A success message, confirming that a member has 'signed up' and created an account",
"Thank you for subscribing to {{siteTitle}}!": "A success message, confirming that a member has 'subscribed' to a newsletter",
diff --git a/ghost/i18n/locales/cs/search.json b/ghost/i18n/locales/cs/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/cs/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/da/search.json b/ghost/i18n/locales/da/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/da/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/de/search.json b/ghost/i18n/locales/de/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/de/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/en/search.json b/ghost/i18n/locales/en/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/en/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/eo/search.json b/ghost/i18n/locales/eo/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/eo/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/es/search.json b/ghost/i18n/locales/es/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/es/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/fa/search.json b/ghost/i18n/locales/fa/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/fa/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/fi/search.json b/ghost/i18n/locales/fi/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/fi/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/fr/search.json b/ghost/i18n/locales/fr/search.json
new file mode 100644
index 0000000000..898b1f4f32
--- /dev/null
+++ b/ghost/i18n/locales/fr/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "Auteurs",
+ "Cancel": "Annuler",
+ "No matches found": "Aucun résultat trouvé",
+ "Posts": "Articles",
+ "Search posts, tags and authors": "Rechercher des articles, des catégories et des auteurs",
+ "Show more results": "Plus de résultats",
+ "Tags": "Catégories"
+}
diff --git a/ghost/i18n/locales/gd/search.json b/ghost/i18n/locales/gd/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/gd/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/hr/search.json b/ghost/i18n/locales/hr/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/hr/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/hu/search.json b/ghost/i18n/locales/hu/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/hu/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/id/search.json b/ghost/i18n/locales/id/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/id/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/is/search.json b/ghost/i18n/locales/is/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/is/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/it/search.json b/ghost/i18n/locales/it/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/it/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/ja/search.json b/ghost/i18n/locales/ja/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/ja/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/ko/search.json b/ghost/i18n/locales/ko/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/ko/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/lt/search.json b/ghost/i18n/locales/lt/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/lt/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/mn/search.json b/ghost/i18n/locales/mn/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/mn/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/ms/search.json b/ghost/i18n/locales/ms/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/ms/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/nl/search.json b/ghost/i18n/locales/nl/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/nl/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/nn/search.json b/ghost/i18n/locales/nn/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/nn/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/no/search.json b/ghost/i18n/locales/no/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/no/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/pl/search.json b/ghost/i18n/locales/pl/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/pl/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/pt-BR/search.json b/ghost/i18n/locales/pt-BR/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/pt-BR/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/pt/search.json b/ghost/i18n/locales/pt/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/pt/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/ro/search.json b/ghost/i18n/locales/ro/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/ro/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/ru/search.json b/ghost/i18n/locales/ru/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/ru/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/si/search.json b/ghost/i18n/locales/si/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/si/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/sk/search.json b/ghost/i18n/locales/sk/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/sk/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/sl/search.json b/ghost/i18n/locales/sl/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/sl/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/sq/search.json b/ghost/i18n/locales/sq/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/sq/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/sr/search.json b/ghost/i18n/locales/sr/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/sr/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/sv/search.json b/ghost/i18n/locales/sv/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/sv/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/tr/search.json b/ghost/i18n/locales/tr/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/tr/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/uk/search.json b/ghost/i18n/locales/uk/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/uk/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/uz/search.json b/ghost/i18n/locales/uz/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/uz/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/vi/search.json b/ghost/i18n/locales/vi/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/vi/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/zh-Hant/search.json b/ghost/i18n/locales/zh-Hant/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/zh-Hant/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/locales/zh/search.json b/ghost/i18n/locales/zh/search.json
new file mode 100644
index 0000000000..8902015528
--- /dev/null
+++ b/ghost/i18n/locales/zh/search.json
@@ -0,0 +1,9 @@
+{
+ "Authors": "",
+ "Cancel": "",
+ "No matches found": "",
+ "Posts": "",
+ "Search posts, tags and authors": "",
+ "Show more results": "",
+ "Tags": ""
+}
diff --git a/ghost/i18n/package.json b/ghost/i18n/package.json
index ba1b8c69b6..3a5257a5b3 100644
--- a/ghost/i18n/package.json
+++ b/ghost/i18n/package.json
@@ -13,11 +13,12 @@
"lint:code": "eslint *.js lib/ --ext .js --cache",
"lint": "yarn lint:code && yarn lint:test",
"lint:test": "eslint -c test/.eslintrc.js test/ --ext .js --cache",
- "translate": "yarn translate:ghost && yarn translate:portal && yarn translate:signup-form && yarn translate:comments && node generate-context.js",
+ "translate": "yarn translate:ghost && yarn translate:portal && yarn translate:signup-form && yarn translate:comments && yarn translate:search && node generate-context.js",
"translate:ghost": "NAMESPACE=ghost i18next '../core/core/{frontend,server,shared}/**/*.{js,jsx}'",
"translate:portal": "NAMESPACE=portal i18next '../../apps/portal/src/**/*.{js,jsx}'",
"translate:signup-form": "NAMESPACE=signup-form i18next '../../apps/signup-form/src/**/*.{ts,tsx}'",
- "translate:comments": "NAMESPACE=comments i18next '../../apps/comments-ui/src/**/*.{ts,tsx}'"
+ "translate:comments": "NAMESPACE=comments i18next '../../apps/comments-ui/src/**/*.{ts,tsx}'",
+ "translate:search": "NAMESPACE=search i18next '../../apps/sodo-search/src/**/*.{js,jsx,ts,tsx}'"
},
"files": [
"index.js",