
Product
Announcing Socket Fix 2.0
Socket Fix 2.0 brings targeted CVE remediation, smarter upgrade planning, and broader ecosystem support to help developers get to zero alerts.
tina-graphql-gateway
Advanced tools
Heads up - if you haven't already done so, read through the CLI documentation to make sure you have a GraphQL server running locally.
For a real-world example of how this is being used checkout the Tina Cloud Starter.
Npm:
npm install --save-dev tina-graphql-gateway
Yarn:
yarn add --dev tina-graphql-gateway
This package exports a class which acts as TinaCMS external API for the Tina Content API. This is a headless GraphQL API that's serverd via Tina Cloud or locally from within the Tina CLI.
import { Client, LocalClient } from "tina-graphql-gateway";
const client = new Client({
organizationId: "the ID you get from Tina Cloud",
clientId: "the client ID you get from Tina Cloud",
branch: "main",
tokenStorage: "LOCAL_STORAGE" | "MEMORY" | "CUSTOM",
});
// For a simpler setup while working locally you can instantiate the LocalClient as a convenience
const client = new LocalClient();
The Client
does a few things:
request
function for working with the GraphQL APIStart by initializing the LocalClient
- which automatically connects with your locally-running GraphQL server. From there, you can make GraphQL requests:
client.request
const client = new LocalClient();
await client.request(
(gql) => gql`#graphql
query BlogPostQuery($relativePath: String!) {
{
getPostsDocument(relativePath: "") {
data {
title
}
}
}
}
`,
{ variables: { relativePath: "hello-world.md" } }
);
This API currently doesn't support filtering and sorting "list" queries. We have plans to tackle that in upcoming cycles.
useGraphQLForms
While GraphQL is a great tool, using it with Tina can be difficult. GraphQL can query across multiple nodes, but since each document would require its own Tina form it could be difficult to sync the data with your query with all of the forms you'd need to build. The Tina GraphQL server knows all about your content schema so we're actually able to build forms automatically by inspecting your query. To see this in action, pass your query into the useGraphqlForms
hook:
import { useGraphqlForms } from 'tina-graphql-gateway'
const query = gql => gql`#graphql
query BlogPostQuery($relativePath: String!) {
{
getPostsDocument(relativePath: $relativePath) {
data {
title
}
}
}
}
`
const MyPage = (props) => {
const [payload, isLoading] = useGraphqlForms<PostQueryResponseType>({
query,
variables: { relativePath: `${props.filename}.md` },
});
isLoading ? <div>Loading...</div> : <MyComponent {...payload}>
}
If Tina is enabled you can see a form for the getPostsDocument
request. If you query for multiple documents, you should see multiple forms:
const query = (gql) => gql`#graphql
query BlogPostQuery($relativePath: String!) {
{
# this generates a Tina Form
getSiteNavsDocument(relativePath: "site-nav.md") {
data {
items {
title
link
}
}
}
# this generates a separate Tina Form
getPostsDocument(relativePath: $relativePath) {
data {
title
}
}
}
}
`;
If you'd like to control the output of those forms, tap into the formify
callback:
import { useGraphqlForms } from "tina-graphql-gateway";
import { Form, GlobalFormPlugin, useCMS } from "tinacms";
const [payload, isLoading] = useGraphqlForms({
query,
formify: ({ formConfig, createForm, skip }) => {
if (formConfig.id === "getSiteNavsDocument") {
const form = new Form(formConfig);
// The site nav will be a global plugin
cms.plugins.add(new GlobalFormPlugin(form));
return form;
}
return createForm(formConfig);
},
variables: { relativePath: `${props.filename}.md` },
});
// or to skip the nav from creating a form altogether:
const [payload, isLoading] = useGraphqlForms({
query,
formify: ({ formConfig, createForm, skip }) => {
if (formConfig.id === "getSiteNavsDocument") {
return skip();
}
return createForm(formConfig);
},
variables: { relativePath: `${props.filename}.md` },
});
Since your forms are built automatically, formify
can also be used to customize fields:
const [payload, isLoading] = useGraphqlForms({
query,
formify: ({ formConfig, createForm, skip }) => {
return createForm({
...formConfig,
fields: formConfig.fields.map((field) => {
if (field.name === "title") {
// replace `text` with `textarea`
field.component = "textarea";
}
return field;
}),
});
},
variables: { relativePath: `${props.filename}.md` },
});
useDocumentCreatorPlugin
This hook allows your editors to safely create new pages. Note that you'll be responsible for redirecting the user after a new document has been created. To use this:
import { useDocumentCreatorPlugin } from "tina-graphql-gateway";
// args is of type:
// {
// collection: {
// slug: string;
// };
// relativePath: string;
// breadcrumbs: string[];
// path: string;
// }
useDocumentCreatorPlugin((args) => window.location.assign(buildMyRouter(args)));
To prevent editors from creating documents from certain collections, provide a filter function:
// options are of type:
// {
// label: string;
// value: string;
// }[]
useDocumentCreatorPlugin(null, (options) =>
options.filter((option) => option.name !== "post")
);
While this package comes with low-level APIs for authentication with Tina Cloud, the easiest way to get started is to use the TinaCloudAuthWall
component, which prevents children from rendering until a valid session has been established with Tina Cloud.
TinaCloudAuthWall
import { TinaCloudAuthWall, Client } from "tina-graphql-gateway";
const TinaWrapper = ({ children }) => {
const cms = React.useMemo(() => {
return new TinaCMS({
apis: {
tina: new Client({
// config
})
},
...
});
}, []);
return <TinaCloudAuthWall cms={cms}>{children}</TinaCloudAuthWall>;
};
Props for TinaCloudAuthWall
Prop | Description |
---|---|
cms | An instance of a CMS |
getModalActions (optional) | A function that returns a list of actions / buttons that will be rendered to the model. Each button has name, action, and can be primary or not. The name is the text that will be displayed. The action is a function that will be run when the button is clicked. See example below for more details |
return (
<TinaCloudAuthWall
cms={cms}
getModalActions={({ closeModal }) => {
return [
{
action: async () => {
// use your own state to get in and out of edit mode
closeModal();
},
name: "close",
primary: false,
},
];
}}
>
<Component {...pageProps} />
</TinaCloudAuthWall>
);
Note: when using the LocalClient, TinaCloudAuthWall won't display a login screen, there is no authentication for the local GraphQL server.
You can also authenticate with the Client
directly:
const client = new Client({
// config
});
const EditSiteButton = () => {
const cms = useCMS();
const onClick = async () => {
await client.authenticate().then((token) => {
cms.enable();
});
};
return <button onClick={onClick}>Edit This Site</button>;
};
FAQs
Unknown package
The npm package tina-graphql-gateway receives a total of 118 weekly downloads. As such, tina-graphql-gateway popularity was classified as not popular.
We found that tina-graphql-gateway demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 13 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
Socket Fix 2.0 brings targeted CVE remediation, smarter upgrade planning, and broader ecosystem support to help developers get to zero alerts.
Security News
Socket CEO Feross Aboukhadijeh joins Risky Business Weekly to unpack recent npm phishing attacks, their limited impact, and the risks if attackers get smarter.
Product
Socket’s new Tier 1 Reachability filters out up to 80% of irrelevant CVEs, so security teams can focus on the vulnerabilities that matter.