Skip to content

Commit

Permalink
Updated URL structure
Browse files Browse the repository at this point in the history
Updated the link structure to improve SEO for community content.

Instead of 'hive-xxxxxx' in the URL, this is replaced by the communtiy name (switched to lower case and special characters removed/updated) or if this is invalid, the 1st tag of the user content.

This update also includes implementation of updated 'canonical-url' information so that Google prioritises the more SEO friendly URL.
  • Loading branch information
the-gorilla-steem committed Jan 28, 2025
1 parent 083efb4 commit a7fd665
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 4 deletions.
47 changes: 46 additions & 1 deletion src/app/components/cards/PostFull.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ import userIllegalContent from 'app/utils/userIllegalContent';
import ImageUserBlockList from 'app/utils/ImageUserBlockList';
import LoadingIndicator from 'app/components/elements/LoadingIndicator';
import { allowDelete } from 'app/utils/StateFunctions';
import ContentEditedWrapper from '../elements/ContentEditedWrapper';
import { Role } from 'app/utils/Community';
import ContentEditedWrapper from '../elements/ContentEditedWrapper';

function TimeAuthorCategory({ post }) {
return (
Expand Down Expand Up @@ -268,6 +268,51 @@ class PostFull extends React.Component {
if (process.env.BROWSER && title)
document.title = title + ' — ' + APP_NAME;

if (process.env.BROWSER) {
const canonicalLink = document.getElementById('canonicalUrlID');
if (!canonicalLink) {
const newCanonicalUrlID = document.createElement('link');
newCanonicalUrlID.rel = 'canonical';
newCanonicalUrlID.key = 'canonical';
newCanonicalUrlID.id = 'canonicalUrlID';
document.head.appendChild(newCanonicalUrlID);
}
if (canonicalLink) {
let tempCategory = category || '';
const tags = content.json_metadata.tags || [];

// Leave Options 1 and 2 uncommented for a combination of both approaches
// Option 1: Replace hive-xxxxxx in the URL with the community name. This doesn't impact non-community posts
const communityTitle =
content.community_title || `#${tempCategory}` || '';
const sanitizedTitle = communityTitle
.replace(/[^a-zA-Z0-9 ]/g, '')
.trim();
const urlFriendlyTitle = sanitizedTitle
.replace(/\s+/g, '-')
.toLowerCase();
if (urlFriendlyTitle) {
tempCategory = urlFriendlyTitle;
}

// Option 2: Replace hive-xxxxxx in the URL with the first tag of a post
if (tempCategory.startsWith('hive-') && tags.length > 0) {
const firstTag = tags[0].startsWith('#')
? tags[0].substring(1)
: tags[0];
tempCategory =
firstTag.startsWith('hive-') && tags.length > 1
? tags[1]
: firstTag; // Sometimes the first tag is still the community & need to check if there's a second tag
tempCategory = tempCategory.startsWith('#')
? tempCategory.substring(1)
: tempCategory;
}
const canonicalURL = `/${tempCategory}/@${author}/${permlink}`;
canonicalLink.href = 'https://' + APP_DOMAIN + canonicalURL;
}
}

let content_body = post.get('body');
const bDMCAStop = DMCAList.includes(link);
const bIllegalContentUser = userIllegalContent.includes(author);
Expand Down
34 changes: 33 additions & 1 deletion src/app/components/cards/PostSummary.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,39 @@ class PostSummary extends React.Component {
const author = post.get('author');
const permlink = post.get('permlink');
const category = post.get('category');
const post_url = `/${category}/@${author}/${permlink}`;

let tempCategory = category || '';
const tags = post.getIn(['json_metadata', 'tags']) || [];

// Leave Options 1 and 2 uncommented for a combination of both approaches
// Option 1: Replace hive-xxxxxx in the URL with the community name. This doesn't impact non-community posts
const communityTitle =
post.get('community_title', '#' + tempCategory) || '';
const sanitizedTitle = communityTitle
.replace(/[^a-zA-Z0-9 ]/g, '')
.trim();
const urlFriendlyTitle = sanitizedTitle
.replace(/\s+/g, '-')
.toLowerCase();
if (urlFriendlyTitle) {
tempCategory = urlFriendlyTitle;
}

// Option 2: Replace hive-xxxxxx in the URL with the first tag of a post
if (tempCategory.startsWith('hive-') && tags && tags.size > 0) {
const firstTag = tags.get(0).startsWith('#')
? tags.get(0).substring(1)
: tags.get(0);
tempCategory =
firstTag.startsWith('hive-') && tags.size > 1
? tags.get(1)
: firstTag; // Sometimes the first tag is still the community & need to check if there's a second tag
tempCategory = tempCategory.startsWith('#')
? tempCategory.substring(1)
: tempCategory;
}

const post_url = `/${tempCategory}/@${author}/${permlink}`;

const summary = extractBodySummary(post.get('body'), isReply);
const keyWord = process.env.BROWSER
Expand Down
16 changes: 15 additions & 1 deletion src/app/components/modules/Header/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { parseJsonTags } from 'app/utils/StateFunctions';
import Headroom from 'react-headroom';
import resolveRoute from 'app/ResolveRoute';
import tt from 'counterpart';
import { APP_NAME } from 'app/client_config';
import { APP_NAME, APP_DOMAIN } from 'app/client_config';
import ElasticSearchInput from 'app/components/elements/ElasticSearchInput';
import IconButton from 'app/components/elements/IconButton';
import DropdownMenu from 'app/components/elements/DropdownMenu';
Expand Down Expand Up @@ -250,6 +250,20 @@ class Header extends React.Component {
)
document.title = page_title + ' — ' + APP_NAME;

if (process.env.BROWSER && route.page !== 'Post') {
const canonicalLink = document.getElementById('canonicalUrlID');
if (canonicalLink) {
canonicalLink.href = 'https://' + APP_DOMAIN + pathname;
} else {
const newCanonicalUrlID = document.createElement('link');
newCanonicalUrlID.rel = 'canonical';
newCanonicalUrlID.key = 'canonical';
newCanonicalUrlID.id = 'canonicalUrlID';
newCanonicalUrlID.href = 'https://' + APP_DOMAIN + pathname;
document.head.appendChild(newCanonicalUrlID);
}
}

//const _feed = current_account_name && `/@${current_account_name}/feed`;
//const logo_link = _feed && pathname != _feed ? _feed : '/';
const logo_link = '/';
Expand Down
29 changes: 28 additions & 1 deletion src/app/utils/CanonicalLinker.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,36 @@ function read_md_canonical(metadata) {

function build_scheme(scheme, post) {
// https://github.com/bonustrack/steemscript/blob/master/apps.json
let tempCategory = post.category || '';

const tags = post.json_metadata.tags || [];

// Leave Options 1 and 2 uncommented for a combination of both approaches
// Option 1: Replace hive-xxxxxx in the URL with the community name. This doesn't impact non-community posts
const communityTitle = post.community_title || `#${tempCategory}` || '';
const sanitizedTitle = communityTitle.replace(/[^a-zA-Z0-9 ]/g, '').trim();
const urlFriendlyTitle = sanitizedTitle.replace(/\s+/g, '-').toLowerCase();
if (urlFriendlyTitle) {
tempCategory = urlFriendlyTitle;
}

// Option 2: Replace hive-xxxxxx in the URL with the first tag of a post
if (tempCategory.startsWith('hive-') && tags.length > 0) {
const firstTag = tags[0].startsWith('#')
? tags[0].substring(1)
: tags[0];
tempCategory =
firstTag.startsWith('hive-') && tags.length > 1
? tags[1]
: firstTag; // Sometimes the first tag is still the community & need to check if there's a second tag
tempCategory = tempCategory.startsWith('#')
? tempCategory.substring(1)
: tempCategory;
}

return scheme
.split('{category}')
.join(post.category)
.join(tempCategory)
.split('{username}')
.join(post.author)
.split('{permlink}')
Expand Down
1 change: 1 addition & 0 deletions src/server/server-html.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export default function ServerHTML({
key="canonical"
rel="canonical"
href={m.canonical}
id="canonicalUrlID"
/>
);
if (m.name && m.content)
Expand Down

0 comments on commit a7fd665

Please sign in to comment.