SEO improvements

This commit is contained in:
Jordan Eldredge 2020-11-11 20:27:46 -08:00
parent 2136696fa2
commit a26e7773cc
4 changed files with 81 additions and 59 deletions

View file

@ -13,7 +13,12 @@ ID = "be420a16-4ef3-43b1-ac62-35869bdf8679"
# Default build command.
command = "npm run build"
[[redirects]]
from = "/sitemap.xml*"
to = "https://api.webamp.org/sitemap.xml"
status = 200
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
status = 200

View file

@ -52,7 +52,7 @@ function FocusedSkin() {
const [previewLoaded, setPreviewLoaded] = useState(initialPosition != null);
const centeredState = useCenteredState();
const closeModal = useActionCreator(Actions.closeModal);
const skinData = useSelector((state) => state.skins[hash] || null);
const skinData = useSelector(Selectors.getSelectedSkinData);
const pos =
initialPosition == null || centered ? centeredState : initialPosition;

View file

@ -4,56 +4,51 @@ import { Helmet } from "react-helmet";
import * as Selectors from "./redux/selectors";
import { SCREENSHOT_WIDTH, SCREENSHOT_HEIGHT } from "./constants";
class Head extends React.Component {
render() {
return (
<Helmet>
<meta charSet="utf-8" />
<title>{this.props.pageTitle}</title>
<link
rel="canonical"
href={`https://skins.webamp.org${this.props.url}`}
/>
<meta property="og:title" content={this.props.pageTitle} />
function Head(props) {
return (
<Helmet canUseDOM={true}>
<meta charSet="utf-8" />
<title>{props.pageTitle}</title>
<link rel="canonical" href={`https://skins.webamp.org${props.url}`} />
<meta property="og:title" content={props.pageTitle} />
<meta
property="og:description"
content="Infinite scroll through 65k Winamp skins with interactive preview"
/>
<meta
property="og:url"
content={`https://skins.webamp.org${props.url}`}
/>
<meta property="og:site-name" content="Winamp Skin Museum" />
{props.previewImageUrl && [
<meta
property="og:description"
content="Infinite scroll through 65k Winamp skins with interactive preview"
/>
property="og:image"
key="og:image"
content={props.previewImageUrl}
/>,
<meta
property="og:url"
content={`https://skins.webamp.org${this.props.url}`}
/>
<meta property="og:site-name" content="Winamp Skin Museum" />
{this.props.previewImageUrl && [
<meta
property="og:image"
key="og:image"
content={this.props.previewImageUrl}
/>,
<meta
property="og:image:type"
key="og:image:type"
content="image/png"
/>,
<meta
property="og:image:width"
key="og:image:width"
content={SCREENSHOT_WIDTH}
/>,
<meta
property="og:image:height"
key="og:image:height"
content={SCREENSHOT_HEIGHT}
/>,
<meta
property="og:image:alt"
key="og:image:alt"
content={"Screenshot of a Winamp skin"}
/>,
]}
</Helmet>
);
}
property="og:image:type"
key="og:image:type"
content="image/png"
/>,
<meta
property="og:image:width"
key="og:image:width"
content={SCREENSHOT_WIDTH}
/>,
<meta
property="og:image:height"
key="og:image:height"
content={SCREENSHOT_HEIGHT}
/>,
<meta
property="og:image:alt"
key="og:image:alt"
content={"Screenshot of a Winamp skin"}
/>,
]}
</Helmet>
);
}
const mapStateToProps = (state) => ({

View file

@ -10,6 +10,15 @@ export function getSelectedSkinPosition(state) {
return state.selectedSkinPosition;
}
export function getSelectedSkinData(state) {
const hash = getSelectedSkinHash(state);
if (hash == null) {
return null;
}
return state.skins[hash] || null;
}
export function overlayShouldAnimate(state) {
return getSelectedSkinPosition(state) != null;
}
@ -136,44 +145,57 @@ export const getAbsolutePermalinkUrlFromHashGetter = createSelector(
}
);
export const getUrl = createSelector(
export const getRouteData = createSelector(
getActiveContentPage,
getSelectedSkinHash,
getSearchQuery,
getFileExplorerOpen,
getFocusedSkinFile,
getPermalinkUrlFromHashGetter,
getSelectedSkinData,
(
activeContentPage,
hash,
query,
fileExplorerOpen,
focusedSkinFile,
getPermalinkUrlFromHash
getPermalinkUrlFromHash,
skinData
) => {
if (activeContentPage === ABOUT_PAGE) {
return "/about/";
return { url: "/about/", title: "About" };
}
if (activeContentPage === UPLOAD_PAGE) {
return "/upload/";
return { url: "/upload/", title: "Upload Skins" };
}
if (hash) {
const skinUrl = getPermalinkUrlFromHash(hash);
if (fileExplorerOpen && focusedSkinFile) {
return `${skinUrl}files/${encodeURIComponent(
const url = `${skinUrl}files/${encodeURIComponent(
focusedSkinFile.fileName
)}`;
return { url, title: skinData?.fileName };
}
return skinUrl;
return { url: skinUrl, title: skinData?.fileName };
} else if (query) {
return `/?query=${encodeURIComponent(query)}`;
return {
url: `/?query=${encodeURIComponent(query)}`,
title: `Search: ${query}`,
};
}
return "/";
return { url: "/", title: null };
}
);
export const getUrl = createSelector(getRouteData, (routeData) => {
return routeData.url;
});
export function getPageTitle(state) {
return "Winamp Skin Museum";
const routeData = getRouteData(state);
const pageTitle = routeData.title;
const siteTitle = "Winamp Skin Museum";
return [pageTitle, siteTitle].filter(Boolean).join(" - ");
}
export const getPreviewImageUrl = createSelector(